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(b'/'), basename))
129
dir_split_paths.append((dirname.split('/'), 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 = [b'', b'a', b'b', b'c', b'd']
135
paths = ['', 'a', 'b', 'c', '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, 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)
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)
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(b'/'), []) for path in paths]
312
split_dirblocks = [(path.split('/'), []) 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 = [b'', b'a', b'b', b'c', b'd']
318
paths = ['', 'a', 'b', 'c', '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, 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')
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')
332
332
def test_involved(self):
333
333
"""This is where bisect_left diverges slightly."""
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',
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',
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
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',
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',
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, 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'')
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/', '')
429
429
def test_cmp_same_str(self):
430
430
"""Compare the same string"""
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')
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')
448
447
def test_simple_paths(self):
449
448
"""Compare strings that act like normal string comparison"""
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')
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')
472
471
def test_tricky_paths(self):
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')
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')
479
478
def test_cmp_unicode_not_allowed(self):
480
479
lt_by_dirs = self.get_lt_by_dirs()
481
self.assertRaises(TypeError, lt_by_dirs, u'Unicode', b'str')
482
self.assertRaises(TypeError, lt_by_dirs, b'str', u'Unicode')
480
self.assertRaises(TypeError, lt_by_dirs, u'Unicode', 'str')
481
self.assertRaises(TypeError, lt_by_dirs, 'str', u'Unicode')
483
482
self.assertRaises(TypeError, lt_by_dirs, u'Unicode', u'Unicode')
485
484
def test_cmp_non_ascii(self):
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'
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'
493
492
class TestCompiledLtByDirs(TestLtByDirs):
534
533
for idx2, path2 in enumerate(paths):
535
534
lt_result = lt_path_by_dirblock(path1, path2)
536
535
self.assertEqual(idx1 < idx2, lt_result,
537
'%s did not state that %r < %r, lt=%s'
538
% (lt_path_by_dirblock.__name__,
539
path1, path2, lt_result))
536
'%s did not state that %r < %r, lt=%s'
537
% (lt_path_by_dirblock.__name__,
538
path1, path2, lt_result))
541
540
def test_cmp_simple_paths(self):
542
541
"""Compare against the empty string."""
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'])
542
self.assertLtPathByDirblock(['', 'a', 'ab', 'abc', 'a/b/c', 'b/d/e'])
543
self.assertLtPathByDirblock(['kl', 'ab/cd', 'ab/ef', 'gh/ij'])
547
545
def test_tricky_paths(self):
548
546
self.assertLtPathByDirblock([
550
b'', b'a', b'a-a', b'a=a', b'b',
548
'', 'a', 'a-a', 'a=a', 'b',
551
549
# Contents of 'a'
552
b'a/a', b'a/a-a', b'a/a=a', b'a/b',
550
'a/a', 'a/a-a', 'a/a=a', 'a/b',
553
551
# Contents of 'a/a'
554
b'a/a/a', b'a/a/a-a', b'a/a/a=a',
552
'a/a/a', 'a/a/a-a', 'a/a/a=a',
555
553
# Contents of 'a/a/a'
556
b'a/a/a/a', b'a/a/a/b',
554
'a/a/a/a', 'a/a/a/b',
557
555
# Contents of 'a/a/a-a',
558
b'a/a/a-a/a', b'a/a/a-a/b',
556
'a/a/a-a/a', 'a/a/a-a/b',
559
557
# Contents of 'a/a/a=a',
560
b'a/a/a=a/a', b'a/a/a=a/b',
558
'a/a/a=a/a', 'a/a/a=a/b',
561
559
# Contents of 'a/a-a'
563
561
# Contents of 'a/a-a/a'
564
b'a/a-a/a/a', b'a/a-a/a/b',
562
'a/a-a/a/a', 'a/a-a/a/b',
565
563
# Contents of 'a/a=a'
567
565
# Contents of 'a/b'
569
567
# Contents of 'a-a',
571
569
# Contents of 'a=a',
573
571
# Contents of 'b',
576
574
self.assertLtPathByDirblock([
578
b'', b'a', b'a-a', b'a-z', b'a=a', b'a=z',
576
'', 'a', 'a-a', 'a-z', 'a=a', 'a=z',
579
577
# content of 'a/'
580
b'a/a', b'a/a-a', b'a/a-z',
582
b'a/z', b'a/z-a', b'a/z-z',
578
'a/a', 'a/a-a', 'a/a-z',
580
'a/z', 'a/z-a', 'a/z-z',
584
582
# content of 'a/a/'
586
584
# content of 'a/a-a'
588
586
# content of 'a/a-z'
590
588
# content of 'a/a=a'
592
590
# content of 'a/a=z'
594
592
# content of 'a/z/'
596
594
# content of 'a-a'
598
596
# content of 'a-z'
600
598
# content of 'a=a'
602
600
# content of 'a=z'
606
604
def test_unicode_not_allowed(self):
607
605
lt_path_by_dirblock = self.get_lt_path_by_dirblock()
651
649
self.assertEqual(expected, _py_memrchr(s, c))
653
651
def test_missing(self):
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')
652
self.assertMemRChr(None, '', 'a')
653
self.assertMemRChr(None, '', 'c')
654
self.assertMemRChr(None, 'abcdefghijklm', 'q')
655
self.assertMemRChr(None, 'aaaaaaaaaaaaaaaaaaaaaaa', 'b')
659
657
def test_single_entry(self):
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')
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')
667
665
def test_multiple(self):
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')
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')
676
674
def test_with_nulls(self):
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')
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')
687
685
class TestReadDirblocks(test_dirstate.TestCaseWithDirState):
977
975
# Because the stat_value looks new, we should re-read the target
978
976
del state._log[:]
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)],
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)],
986
state.adjust_time(+20) # Skip into the future, all files look old
984
state.adjust_time(+20) # Skip into the future, all files look old
987
985
del state._log[:]
988
link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
989
stat_value=stat_value)
986
link_or_sha1 = self.update_entry(state, entry, abspath='a',
987
stat_value=stat_value)
990
988
# The symlink stayed a symlink. So while it is new enough to cache, we
991
989
# don't bother setting the flag, because it is not really worth saving
992
990
# (when we stat the symlink, we'll have paged in the target.)
993
991
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
994
992
state._dirblock_state)
995
self.assertEqual(b'target', link_or_sha1)
993
self.assertEqual('target', link_or_sha1)
996
994
# We need to re-read the link because only now can we cache it
997
self.assertEqual([('read_link', b'a', b'')], state._log)
998
self.assertEqual([(b'l', b'target', 6, False, packed_stat)],
995
self.assertEqual([('read_link', 'a', '')], state._log)
996
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1001
999
del state._log[:]
1002
1000
# Another call won't re-read the link
1003
1001
self.assertEqual([], state._log)
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)],
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)],
1010
1008
def do_update_entry(self, state, entry, abspath):
1200
1198
state, entry = self.get_state_with_a()
1201
1199
self.build_tree(['a'])
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
1201
# Make sure we are using the win32 implementation of _is_executable
1202
state._is_executable = state._is_executable_win32
1207
1204
# The file on disk is not executable, but we are marking it as though
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)
1205
# it is. With _is_executable_win32 we ignore what is on disk.
1206
entry[1][0] = ('f', '', 0, True, dirstate.DirState.NULLSTAT)
1212
1208
stat_value = os.lstat('a')
1213
1209
packed_stat = dirstate.pack_stat(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)
1211
state.adjust_time(-10) # Make sure everything is new
1212
self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1218
1214
# The row is updated, but the executable bit stays set.
1219
self.assertEqual([(b'f', b'', 14, True, dirstate.DirState.NULLSTAT)],
1215
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1222
1218
# Make the disk object look old enough to cache (but it won't cache the
1223
1219
# sha as it is a new file).
1224
1220
state.adjust_time(+20)
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)],
1221
digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1222
self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1223
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1230
1226
def _prepare_tree(self):
1231
1227
# Create a tree