120
120
bisect_split_idx, bisect_path_idx, path)
123
self.assertEqual(path, paths[bisect_path_idx+offset])
123
self.assertEqual(path, paths[bisect_path_idx + offset])
125
125
def split_for_dirblocks(self, paths):
126
126
dir_split_paths = []
127
127
for path in paths:
128
128
dirname, basename = os.path.split(path)
129
dir_split_paths.append((dirname.split('/'), basename))
129
dir_split_paths.append((dirname.split(b'/'), basename))
130
130
dir_split_paths.sort()
131
131
return dir_split_paths
133
133
def test_simple(self):
134
134
"""In the simple case it works just like bisect_left"""
135
paths = ['', 'a', 'b', 'c', 'd']
135
paths = [b'', b'a', b'b', b'c', b'd']
136
136
split_paths = self.split_for_dirblocks(paths)
137
137
for path in paths:
138
138
self.assertBisect(paths, split_paths, path, exists=True)
139
self.assertBisect(paths, split_paths, '_', exists=False)
140
self.assertBisect(paths, split_paths, 'aa', exists=False)
141
self.assertBisect(paths, split_paths, 'bb', exists=False)
142
self.assertBisect(paths, split_paths, 'cc', exists=False)
143
self.assertBisect(paths, split_paths, 'dd', exists=False)
144
self.assertBisect(paths, split_paths, 'a/a', exists=False)
145
self.assertBisect(paths, split_paths, 'b/b', exists=False)
146
self.assertBisect(paths, split_paths, 'c/c', exists=False)
147
self.assertBisect(paths, split_paths, 'd/d', exists=False)
139
self.assertBisect(paths, split_paths, b'_', exists=False)
140
self.assertBisect(paths, split_paths, b'aa', exists=False)
141
self.assertBisect(paths, split_paths, b'bb', exists=False)
142
self.assertBisect(paths, split_paths, b'cc', exists=False)
143
self.assertBisect(paths, split_paths, b'dd', exists=False)
144
self.assertBisect(paths, split_paths, b'a/a', exists=False)
145
self.assertBisect(paths, split_paths, b'b/b', exists=False)
146
self.assertBisect(paths, split_paths, b'c/c', exists=False)
147
self.assertBisect(paths, split_paths, b'd/d', exists=False)
149
149
def test_involved(self):
150
150
"""This is where bisect_path_* diverges slightly."""
309
309
Also, ensure that the paths are in proper sorted order.
311
311
dirblocks = [(path, []) for path in paths]
312
split_dirblocks = [(path.split('/'), []) for path in paths]
312
split_dirblocks = [(path.split(b'/'), []) for path in paths]
313
313
self.assertEqual(sorted(split_dirblocks), split_dirblocks)
314
314
return dirblocks, split_dirblocks
316
316
def test_simple(self):
317
317
"""In the simple case it works just like bisect_left"""
318
paths = ['', 'a', 'b', 'c', 'd']
318
paths = [b'', b'a', b'b', b'c', b'd']
319
319
dirblocks, split_dirblocks = self.paths_to_dirblocks(paths)
320
320
for path in paths:
321
321
self.assertBisect(dirblocks, split_dirblocks, path)
322
self.assertBisect(dirblocks, split_dirblocks, '_')
323
self.assertBisect(dirblocks, split_dirblocks, 'aa')
324
self.assertBisect(dirblocks, split_dirblocks, 'bb')
325
self.assertBisect(dirblocks, split_dirblocks, 'cc')
326
self.assertBisect(dirblocks, split_dirblocks, 'dd')
327
self.assertBisect(dirblocks, split_dirblocks, 'a/a')
328
self.assertBisect(dirblocks, split_dirblocks, 'b/b')
329
self.assertBisect(dirblocks, split_dirblocks, 'c/c')
330
self.assertBisect(dirblocks, split_dirblocks, 'd/d')
322
self.assertBisect(dirblocks, split_dirblocks, b'_')
323
self.assertBisect(dirblocks, split_dirblocks, b'aa')
324
self.assertBisect(dirblocks, split_dirblocks, b'bb')
325
self.assertBisect(dirblocks, split_dirblocks, b'cc')
326
self.assertBisect(dirblocks, split_dirblocks, b'dd')
327
self.assertBisect(dirblocks, split_dirblocks, b'a/a')
328
self.assertBisect(dirblocks, split_dirblocks, b'b/b')
329
self.assertBisect(dirblocks, split_dirblocks, b'c/c')
330
self.assertBisect(dirblocks, split_dirblocks, b'd/d')
332
332
def test_involved(self):
333
333
"""This is where bisect_left diverges slightly."""
335
'a/a', 'a/a/a', 'a/a/z', 'a/a-a', 'a/a-z',
336
'a/z', 'a/z/a', 'a/z/z', 'a/z-a', 'a/z-z',
338
'z', 'z/a/a', 'z/a/z', 'z/a-a', 'z/a-z',
339
'z/z', 'z/z/a', 'z/z/z', 'z/z-a', 'z/z-z',
335
b'a/a', b'a/a/a', b'a/a/z', b'a/a-a', b'a/a-z',
336
b'a/z', b'a/z/a', b'a/z/z', b'a/z-a', b'a/z-z',
338
b'z', b'z/a/a', b'z/a/z', b'z/a-a', b'z/a-z',
339
b'z/z', b'z/z/a', b'z/z/z', b'z/z-a', b'z/z-z',
342
342
dirblocks, split_dirblocks = self.paths_to_dirblocks(paths)
343
343
for path in paths:
344
344
self.assertBisect(dirblocks, split_dirblocks, path)
346
346
def test_involved_cached(self):
347
347
"""This is where bisect_left diverges slightly."""
349
'a/a', 'a/a/a', 'a/a/z', 'a/a-a', 'a/a-z',
350
'a/z', 'a/z/a', 'a/z/z', 'a/z-a', 'a/z-z',
352
'z', 'z/a/a', 'z/a/z', 'z/a-a', 'z/a-z',
353
'z/z', 'z/z/a', 'z/z/z', 'z/z-a', 'z/z-z',
349
b'a/a', b'a/a/a', b'a/a/z', b'a/a-a', b'a/a-z',
350
b'a/z', b'a/z/a', b'a/z/z', b'a/z-a', b'a/z-z',
352
b'z', b'z/a/a', b'z/a/z', b'z/a-a', b'z/a-z',
353
b'z/z', b'z/z/a', b'z/z/z', b'z/z-a', b'z/z-z',
357
357
dirblocks, split_dirblocks = self.paths_to_dirblocks(paths)
358
358
for path in paths:
415
415
def test_cmp_empty(self):
416
416
"""Compare against the empty string."""
417
self.assertCmpByDirs(0, '', '')
418
self.assertCmpByDirs(1, 'a', '')
419
self.assertCmpByDirs(1, 'ab', '')
420
self.assertCmpByDirs(1, 'abc', '')
421
self.assertCmpByDirs(1, 'abcd', '')
422
self.assertCmpByDirs(1, 'abcde', '')
423
self.assertCmpByDirs(1, 'abcdef', '')
424
self.assertCmpByDirs(1, 'abcdefg', '')
425
self.assertCmpByDirs(1, 'abcdefgh', '')
426
self.assertCmpByDirs(1, 'abcdefghi', '')
427
self.assertCmpByDirs(1, 'test/ing/a/path/', '')
417
self.assertCmpByDirs(0, b'', b'')
418
self.assertCmpByDirs(1, b'a', b'')
419
self.assertCmpByDirs(1, b'ab', b'')
420
self.assertCmpByDirs(1, b'abc', b'')
421
self.assertCmpByDirs(1, b'abcd', b'')
422
self.assertCmpByDirs(1, b'abcde', b'')
423
self.assertCmpByDirs(1, b'abcdef', b'')
424
self.assertCmpByDirs(1, b'abcdefg', b'')
425
self.assertCmpByDirs(1, b'abcdefgh', b'')
426
self.assertCmpByDirs(1, b'abcdefghi', b'')
427
self.assertCmpByDirs(1, b'test/ing/a/path/', b'')
429
429
def test_cmp_same_str(self):
430
430
"""Compare the same string"""
431
self.assertCmpByDirs(0, 'a', 'a')
432
self.assertCmpByDirs(0, 'ab', 'ab')
433
self.assertCmpByDirs(0, 'abc', 'abc')
434
self.assertCmpByDirs(0, 'abcd', 'abcd')
435
self.assertCmpByDirs(0, 'abcde', 'abcde')
436
self.assertCmpByDirs(0, 'abcdef', 'abcdef')
437
self.assertCmpByDirs(0, 'abcdefg', 'abcdefg')
438
self.assertCmpByDirs(0, 'abcdefgh', 'abcdefgh')
439
self.assertCmpByDirs(0, 'abcdefghi', 'abcdefghi')
440
self.assertCmpByDirs(0, 'testing a long string', 'testing a long string')
441
self.assertCmpByDirs(0, 'x'*10000, 'x'*10000)
442
self.assertCmpByDirs(0, 'a/b', 'a/b')
443
self.assertCmpByDirs(0, 'a/b/c', 'a/b/c')
444
self.assertCmpByDirs(0, 'a/b/c/d', 'a/b/c/d')
445
self.assertCmpByDirs(0, 'a/b/c/d/e', 'a/b/c/d/e')
431
self.assertCmpByDirs(0, b'a', b'a')
432
self.assertCmpByDirs(0, b'ab', b'ab')
433
self.assertCmpByDirs(0, b'abc', b'abc')
434
self.assertCmpByDirs(0, b'abcd', b'abcd')
435
self.assertCmpByDirs(0, b'abcde', b'abcde')
436
self.assertCmpByDirs(0, b'abcdef', b'abcdef')
437
self.assertCmpByDirs(0, b'abcdefg', b'abcdefg')
438
self.assertCmpByDirs(0, b'abcdefgh', b'abcdefgh')
439
self.assertCmpByDirs(0, b'abcdefghi', b'abcdefghi')
440
self.assertCmpByDirs(0, b'testing a long string',
441
b'testing a long string')
442
self.assertCmpByDirs(0, b'x' * 10000, b'x' * 10000)
443
self.assertCmpByDirs(0, b'a/b', b'a/b')
444
self.assertCmpByDirs(0, b'a/b/c', b'a/b/c')
445
self.assertCmpByDirs(0, b'a/b/c/d', b'a/b/c/d')
446
self.assertCmpByDirs(0, b'a/b/c/d/e', b'a/b/c/d/e')
447
448
def test_simple_paths(self):
448
449
"""Compare strings that act like normal string comparison"""
449
self.assertCmpByDirs(-1, 'a', 'b')
450
self.assertCmpByDirs(-1, 'aa', 'ab')
451
self.assertCmpByDirs(-1, 'ab', 'bb')
452
self.assertCmpByDirs(-1, 'aaa', 'aab')
453
self.assertCmpByDirs(-1, 'aab', 'abb')
454
self.assertCmpByDirs(-1, 'abb', 'bbb')
455
self.assertCmpByDirs(-1, 'aaaa', 'aaab')
456
self.assertCmpByDirs(-1, 'aaab', 'aabb')
457
self.assertCmpByDirs(-1, 'aabb', 'abbb')
458
self.assertCmpByDirs(-1, 'abbb', 'bbbb')
459
self.assertCmpByDirs(-1, 'aaaaa', 'aaaab')
460
self.assertCmpByDirs(-1, 'a/a', 'a/b')
461
self.assertCmpByDirs(-1, 'a/b', 'b/b')
462
self.assertCmpByDirs(-1, 'a/a/a', 'a/a/b')
463
self.assertCmpByDirs(-1, 'a/a/b', 'a/b/b')
464
self.assertCmpByDirs(-1, 'a/b/b', 'b/b/b')
465
self.assertCmpByDirs(-1, 'a/a/a/a', 'a/a/a/b')
466
self.assertCmpByDirs(-1, 'a/a/a/b', 'a/a/b/b')
467
self.assertCmpByDirs(-1, 'a/a/b/b', 'a/b/b/b')
468
self.assertCmpByDirs(-1, 'a/b/b/b', 'b/b/b/b')
469
self.assertCmpByDirs(-1, 'a/a/a/a/a', 'a/a/a/a/b')
450
self.assertCmpByDirs(-1, b'a', b'b')
451
self.assertCmpByDirs(-1, b'aa', b'ab')
452
self.assertCmpByDirs(-1, b'ab', b'bb')
453
self.assertCmpByDirs(-1, b'aaa', b'aab')
454
self.assertCmpByDirs(-1, b'aab', b'abb')
455
self.assertCmpByDirs(-1, b'abb', b'bbb')
456
self.assertCmpByDirs(-1, b'aaaa', b'aaab')
457
self.assertCmpByDirs(-1, b'aaab', b'aabb')
458
self.assertCmpByDirs(-1, b'aabb', b'abbb')
459
self.assertCmpByDirs(-1, b'abbb', b'bbbb')
460
self.assertCmpByDirs(-1, b'aaaaa', b'aaaab')
461
self.assertCmpByDirs(-1, b'a/a', b'a/b')
462
self.assertCmpByDirs(-1, b'a/b', b'b/b')
463
self.assertCmpByDirs(-1, b'a/a/a', b'a/a/b')
464
self.assertCmpByDirs(-1, b'a/a/b', b'a/b/b')
465
self.assertCmpByDirs(-1, b'a/b/b', b'b/b/b')
466
self.assertCmpByDirs(-1, b'a/a/a/a', b'a/a/a/b')
467
self.assertCmpByDirs(-1, b'a/a/a/b', b'a/a/b/b')
468
self.assertCmpByDirs(-1, b'a/a/b/b', b'a/b/b/b')
469
self.assertCmpByDirs(-1, b'a/b/b/b', b'b/b/b/b')
470
self.assertCmpByDirs(-1, b'a/a/a/a/a', b'a/a/a/a/b')
471
472
def test_tricky_paths(self):
472
self.assertCmpByDirs(1, 'ab/cd/ef', 'ab/cc/ef')
473
self.assertCmpByDirs(1, 'ab/cd/ef', 'ab/c/ef')
474
self.assertCmpByDirs(-1, 'ab/cd/ef', 'ab/cd-ef')
475
self.assertCmpByDirs(-1, 'ab/cd', 'ab/cd-')
476
self.assertCmpByDirs(-1, 'ab/cd', 'ab-cd')
473
self.assertCmpByDirs(1, b'ab/cd/ef', b'ab/cc/ef')
474
self.assertCmpByDirs(1, b'ab/cd/ef', b'ab/c/ef')
475
self.assertCmpByDirs(-1, b'ab/cd/ef', b'ab/cd-ef')
476
self.assertCmpByDirs(-1, b'ab/cd', b'ab/cd-')
477
self.assertCmpByDirs(-1, b'ab/cd', b'ab-cd')
478
479
def test_cmp_unicode_not_allowed(self):
479
480
lt_by_dirs = self.get_lt_by_dirs()
480
self.assertRaises(TypeError, lt_by_dirs, u'Unicode', 'str')
481
self.assertRaises(TypeError, lt_by_dirs, 'str', u'Unicode')
481
self.assertRaises(TypeError, lt_by_dirs, u'Unicode', b'str')
482
self.assertRaises(TypeError, lt_by_dirs, b'str', u'Unicode')
482
483
self.assertRaises(TypeError, lt_by_dirs, u'Unicode', u'Unicode')
484
485
def test_cmp_non_ascii(self):
485
self.assertCmpByDirs(-1, '\xc2\xb5', '\xc3\xa5') # u'\xb5', u'\xe5'
486
self.assertCmpByDirs(-1, 'a', '\xc3\xa5') # u'a', u'\xe5'
487
self.assertCmpByDirs(-1, 'b', '\xc2\xb5') # u'b', u'\xb5'
488
self.assertCmpByDirs(-1, 'a/b', 'a/\xc3\xa5') # u'a/b', u'a/\xe5'
489
self.assertCmpByDirs(-1, 'b/a', 'b/\xc2\xb5') # u'b/a', u'b/\xb5'
486
self.assertCmpByDirs(-1, b'\xc2\xb5', b'\xc3\xa5') # u'\xb5', u'\xe5'
487
self.assertCmpByDirs(-1, b'a', b'\xc3\xa5') # u'a', u'\xe5'
488
self.assertCmpByDirs(-1, b'b', b'\xc2\xb5') # u'b', u'\xb5'
489
self.assertCmpByDirs(-1, b'a/b', b'a/\xc3\xa5') # u'a/b', u'a/\xe5'
490
self.assertCmpByDirs(-1, b'b/a', b'b/\xc2\xb5') # u'b/a', u'b/\xb5'
492
493
class TestCompiledLtByDirs(TestLtByDirs):
533
534
for idx2, path2 in enumerate(paths):
534
535
lt_result = lt_path_by_dirblock(path1, path2)
535
536
self.assertEqual(idx1 < idx2, lt_result,
536
'%s did not state that %r < %r, lt=%s'
537
% (lt_path_by_dirblock.__name__,
538
path1, path2, lt_result))
537
'%s did not state that %r < %r, lt=%s'
538
% (lt_path_by_dirblock.__name__,
539
path1, path2, lt_result))
540
541
def test_cmp_simple_paths(self):
541
542
"""Compare against the empty string."""
542
self.assertLtPathByDirblock(['', 'a', 'ab', 'abc', 'a/b/c', 'b/d/e'])
543
self.assertLtPathByDirblock(['kl', 'ab/cd', 'ab/ef', 'gh/ij'])
543
self.assertLtPathByDirblock(
544
[b'', b'a', b'ab', b'abc', b'a/b/c', b'b/d/e'])
545
self.assertLtPathByDirblock([b'kl', b'ab/cd', b'ab/ef', b'gh/ij'])
545
547
def test_tricky_paths(self):
546
548
self.assertLtPathByDirblock([
548
'', 'a', 'a-a', 'a=a', 'b',
550
b'', b'a', b'a-a', b'a=a', b'b',
549
551
# Contents of 'a'
550
'a/a', 'a/a-a', 'a/a=a', 'a/b',
552
b'a/a', b'a/a-a', b'a/a=a', b'a/b',
551
553
# Contents of 'a/a'
552
'a/a/a', 'a/a/a-a', 'a/a/a=a',
554
b'a/a/a', b'a/a/a-a', b'a/a/a=a',
553
555
# Contents of 'a/a/a'
554
'a/a/a/a', 'a/a/a/b',
556
b'a/a/a/a', b'a/a/a/b',
555
557
# Contents of 'a/a/a-a',
556
'a/a/a-a/a', 'a/a/a-a/b',
558
b'a/a/a-a/a', b'a/a/a-a/b',
557
559
# Contents of 'a/a/a=a',
558
'a/a/a=a/a', 'a/a/a=a/b',
560
b'a/a/a=a/a', b'a/a/a=a/b',
559
561
# Contents of 'a/a-a'
561
563
# Contents of 'a/a-a/a'
562
'a/a-a/a/a', 'a/a-a/a/b',
564
b'a/a-a/a/a', b'a/a-a/a/b',
563
565
# Contents of 'a/a=a'
565
567
# Contents of 'a/b'
567
569
# Contents of 'a-a',
569
571
# Contents of 'a=a',
571
573
# Contents of 'b',
574
576
self.assertLtPathByDirblock([
576
'', 'a', 'a-a', 'a-z', 'a=a', 'a=z',
578
b'', b'a', b'a-a', b'a-z', b'a=a', b'a=z',
577
579
# content of 'a/'
578
'a/a', 'a/a-a', 'a/a-z',
580
'a/z', 'a/z-a', 'a/z-z',
580
b'a/a', b'a/a-a', b'a/a-z',
582
b'a/z', b'a/z-a', b'a/z-z',
582
584
# content of 'a/a/'
584
586
# content of 'a/a-a'
586
588
# content of 'a/a-z'
588
590
# content of 'a/a=a'
590
592
# content of 'a/a=z'
592
594
# content of 'a/z/'
594
596
# content of 'a-a'
596
598
# content of 'a-z'
598
600
# content of 'a=a'
600
602
# content of 'a=z'
604
606
def test_unicode_not_allowed(self):
605
607
lt_path_by_dirblock = self.get_lt_path_by_dirblock()
649
651
self.assertEqual(expected, _py_memrchr(s, c))
651
653
def test_missing(self):
652
self.assertMemRChr(None, '', 'a')
653
self.assertMemRChr(None, '', 'c')
654
self.assertMemRChr(None, 'abcdefghijklm', 'q')
655
self.assertMemRChr(None, 'aaaaaaaaaaaaaaaaaaaaaaa', 'b')
654
self.assertMemRChr(None, b'', b'a')
655
self.assertMemRChr(None, b'', b'c')
656
self.assertMemRChr(None, b'abcdefghijklm', b'q')
657
self.assertMemRChr(None, b'aaaaaaaaaaaaaaaaaaaaaaa', b'b')
657
659
def test_single_entry(self):
658
self.assertMemRChr(0, 'abcdefghijklm', 'a')
659
self.assertMemRChr(1, 'abcdefghijklm', 'b')
660
self.assertMemRChr(2, 'abcdefghijklm', 'c')
661
self.assertMemRChr(10, 'abcdefghijklm', 'k')
662
self.assertMemRChr(11, 'abcdefghijklm', 'l')
663
self.assertMemRChr(12, 'abcdefghijklm', 'm')
660
self.assertMemRChr(0, b'abcdefghijklm', b'a')
661
self.assertMemRChr(1, b'abcdefghijklm', b'b')
662
self.assertMemRChr(2, b'abcdefghijklm', b'c')
663
self.assertMemRChr(10, b'abcdefghijklm', b'k')
664
self.assertMemRChr(11, b'abcdefghijklm', b'l')
665
self.assertMemRChr(12, b'abcdefghijklm', b'm')
665
667
def test_multiple(self):
666
self.assertMemRChr(10, 'abcdefjklmabcdefghijklm', 'a')
667
self.assertMemRChr(11, 'abcdefjklmabcdefghijklm', 'b')
668
self.assertMemRChr(12, 'abcdefjklmabcdefghijklm', 'c')
669
self.assertMemRChr(20, 'abcdefjklmabcdefghijklm', 'k')
670
self.assertMemRChr(21, 'abcdefjklmabcdefghijklm', 'l')
671
self.assertMemRChr(22, 'abcdefjklmabcdefghijklm', 'm')
672
self.assertMemRChr(22, 'aaaaaaaaaaaaaaaaaaaaaaa', 'a')
668
self.assertMemRChr(10, b'abcdefjklmabcdefghijklm', b'a')
669
self.assertMemRChr(11, b'abcdefjklmabcdefghijklm', b'b')
670
self.assertMemRChr(12, b'abcdefjklmabcdefghijklm', b'c')
671
self.assertMemRChr(20, b'abcdefjklmabcdefghijklm', b'k')
672
self.assertMemRChr(21, b'abcdefjklmabcdefghijklm', b'l')
673
self.assertMemRChr(22, b'abcdefjklmabcdefghijklm', b'm')
674
self.assertMemRChr(22, b'aaaaaaaaaaaaaaaaaaaaaaa', b'a')
674
676
def test_with_nulls(self):
675
self.assertMemRChr(10, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'a')
676
self.assertMemRChr(11, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'b')
677
self.assertMemRChr(12, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'c')
678
self.assertMemRChr(20, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'k')
679
self.assertMemRChr(21, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'l')
680
self.assertMemRChr(22, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'm')
681
self.assertMemRChr(22, 'aaa\0\0\0aaaaaaa\0\0\0aaaaaaa', 'a')
682
self.assertMemRChr(9, '\0\0\0\0\0\0\0\0\0\0', '\0')
677
self.assertMemRChr(10, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'a')
678
self.assertMemRChr(11, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'b')
679
self.assertMemRChr(12, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'c')
680
self.assertMemRChr(20, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'k')
681
self.assertMemRChr(21, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'l')
682
self.assertMemRChr(22, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'm')
683
self.assertMemRChr(22, b'aaa\0\0\0aaaaaaa\0\0\0aaaaaaa', b'a')
684
self.assertMemRChr(9, b'\0\0\0\0\0\0\0\0\0\0', b'\0')
685
687
class TestReadDirblocks(test_dirstate.TestCaseWithDirState):
975
977
# Because the stat_value looks new, we should re-read the target
976
978
del state._log[:]
977
link_or_sha1 = self.update_entry(state, entry, abspath='a',
978
stat_value=stat_value)
979
self.assertEqual('target', link_or_sha1)
980
self.assertEqual([('read_link', 'a', '')], state._log)
981
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
979
link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
980
stat_value=stat_value)
981
self.assertEqual(b'target', link_or_sha1)
982
self.assertEqual([('read_link', b'a', b'')], state._log)
983
self.assertEqual([(b'l', b'', 6, False, dirstate.DirState.NULLSTAT)],
984
state.adjust_time(+20) # Skip into the future, all files look old
986
state.adjust_time(+20) # Skip into the future, all files look old
985
987
del state._log[:]
986
link_or_sha1 = self.update_entry(state, entry, abspath='a',
987
stat_value=stat_value)
988
link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
989
stat_value=stat_value)
988
990
# The symlink stayed a symlink. So while it is new enough to cache, we
989
991
# don't bother setting the flag, because it is not really worth saving
990
992
# (when we stat the symlink, we'll have paged in the target.)
991
993
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
992
994
state._dirblock_state)
993
self.assertEqual('target', link_or_sha1)
995
self.assertEqual(b'target', link_or_sha1)
994
996
# We need to re-read the link because only now can we cache it
995
self.assertEqual([('read_link', 'a', '')], state._log)
996
self.assertEqual([('l', 'target', 6, False, packed_stat)],
997
self.assertEqual([('read_link', b'a', b'')], state._log)
998
self.assertEqual([(b'l', b'target', 6, False, packed_stat)],
999
1001
del state._log[:]
1000
1002
# Another call won't re-read the link
1001
1003
self.assertEqual([], state._log)
1002
link_or_sha1 = self.update_entry(state, entry, abspath='a',
1003
stat_value=stat_value)
1004
self.assertEqual('target', link_or_sha1)
1005
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1004
link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
1005
stat_value=stat_value)
1006
self.assertEqual(b'target', link_or_sha1)
1007
self.assertEqual([(b'l', b'target', 6, False, packed_stat)],
1008
1010
def do_update_entry(self, state, entry, abspath):
1050
1052
tree = self.make_branch_and_tree('tree')
1051
1053
tree.lock_write()
1052
1054
self.build_tree(['tree/a'])
1053
tree.add(['a'], ['a-id'])
1055
tree.add(['a'], [b'a-id'])
1054
1056
with_a_id = tree.commit('witha')
1055
1057
self.addCleanup(tree.unlock)
1056
1058
state.set_parent_trees(
1057
1059
[(with_a_id, tree.branch.repository.revision_tree(with_a_id))],
1059
entry = state._get_entry(0, path_utf8='a')
1061
entry = state._get_entry(0, path_utf8=b'a')
1060
1062
self.build_tree(['a'])
1061
sha1sum = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1063
sha1sum = b'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1062
1064
state.adjust_time(+20)
1063
self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1065
self.assertEqual(sha1sum, self.do_update_entry(state, entry, b'a'))
1064
1066
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1065
1067
state._dirblock_state)
1067
1069
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1068
1070
state._dirblock_state)
1069
self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1071
self.assertEqual(sha1sum, self.do_update_entry(state, entry, b'a'))
1070
1072
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1071
1073
state._dirblock_state)
1073
1075
def test_update_entry_tree_reference(self):
1074
1076
state = test_dirstate.InstrumentedDirState.initialize('dirstate')
1075
1077
self.addCleanup(state.unlock)
1076
state.add('r', 'r-id', 'tree-reference', None, '')
1078
state.add('r', b'r-id', 'tree-reference', None, b'')
1077
1079
self.build_tree(['r/'])
1078
entry = state._get_entry(0, path_utf8='r')
1080
entry = state._get_entry(0, path_utf8=b'r')
1079
1081
self.do_update_entry(state, entry, 'r')
1080
entry = state._get_entry(0, path_utf8='r')
1081
self.assertEqual('t', entry[1][0][0])
1082
entry = state._get_entry(0, path_utf8=b'r')
1083
self.assertEqual(b't', entry[1][0][0])
1083
1085
def create_and_test_file(self, state, entry):
1084
1086
"""Create a file at 'a' and verify the state finds it during update.
1198
1200
state, entry = self.get_state_with_a()
1199
1201
self.build_tree(['a'])
1201
# Make sure we are using the win32 implementation of _is_executable
1202
state._is_executable = state._is_executable_win32
1203
# Make sure we are using the version of _is_executable that doesn't
1204
# check the filesystem mode.
1205
state._use_filesystem_for_exec = False
1204
1207
# The file on disk is not executable, but we are marking it as though
1205
# it is. With _is_executable_win32 we ignore what is on disk.
1206
entry[1][0] = ('f', '', 0, True, dirstate.DirState.NULLSTAT)
1208
# it is. With _use_filesystem_for_exec disabled we ignore what is on
1210
entry[1][0] = (b'f', b'', 0, True, dirstate.DirState.NULLSTAT)
1208
1212
stat_value = os.lstat('a')
1209
1213
packed_stat = dirstate.pack_stat(stat_value)
1211
state.adjust_time(-10) # Make sure everything is new
1212
self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1215
state.adjust_time(-10) # Make sure everything is new
1216
self.update_entry(state, entry, abspath=b'a', stat_value=stat_value)
1214
1218
# The row is updated, but the executable bit stays set.
1215
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1219
self.assertEqual([(b'f', b'', 14, True, dirstate.DirState.NULLSTAT)],
1218
1222
# Make the disk object look old enough to cache (but it won't cache the
1219
1223
# sha as it is a new file).
1220
1224
state.adjust_time(+20)
1221
digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1222
self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1223
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1225
digest = b'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1226
self.update_entry(state, entry, abspath=b'a', stat_value=stat_value)
1227
self.assertEqual([(b'f', b'', 14, True, dirstate.DirState.NULLSTAT)],
1226
1230
def _prepare_tree(self):
1227
1231
# Create a tree
1228
text = 'Hello World\n'
1232
text = b'Hello World\n'
1229
1233
tree = self.make_branch_and_tree('tree')
1230
1234
self.build_tree_contents([('tree/a file', text)])
1231
tree.add('a file', 'a-file-id')
1235
tree.add('a file', b'a-file-id')
1232
1236
# Note: dirstate does not sha prior to the first commit
1233
1237
# so commit now in order for the test to work
1234
1238
tree.commit('first')