@@ -341,6 +341,42 @@ def reference_find(p, s):
341
341
self .checkequal (reference_find (p , text ),
342
342
text , 'find' , p )
343
343
344
+ def test_find_many_lengths (self ):
345
+ haystack_repeats = [a * 10 ** e for e in range (6 ) for a in (1 ,2 ,5 )]
346
+ haystacks = [(n , self .fixtype ("abcab" * n + "da" )) for n in haystack_repeats ]
347
+
348
+ needle_repeats = [a * 10 ** e for e in range (6 ) for a in (1 , 3 )]
349
+ needles = [(m , self .fixtype ("abcab" * m + "da" )) for m in needle_repeats ]
350
+
351
+ for n , haystack1 in haystacks :
352
+ haystack2 = haystack1 [:- 1 ]
353
+ for m , needle in needles :
354
+ answer1 = 5 * (n - m ) if m <= n else - 1
355
+ self .assertEqual (haystack1 .find (needle ), answer1 , msg = (n ,m ))
356
+ self .assertEqual (haystack2 .find (needle ), - 1 , msg = (n ,m ))
357
+
358
+ def test_adaptive_find (self ):
359
+ # This would be very slow for the naive algorithm,
360
+ # but str.find() should be O(n + m).
361
+ for N in 1000 , 10_000 , 100_000 , 1_000_000 :
362
+ A , B = 'a' * N , 'b' * N
363
+ haystack = A + A + B + A + A
364
+ needle = A + B + B + A
365
+ self .checkequal (- 1 , haystack , 'find' , needle )
366
+ self .checkequal (0 , haystack , 'count' , needle )
367
+ self .checkequal (len (haystack ), haystack + needle , 'find' , needle )
368
+ self .checkequal (1 , haystack + needle , 'count' , needle )
369
+
370
+ def test_find_with_memory (self ):
371
+ # Test the "Skip with memory" path in the two-way algorithm.
372
+ for N in 1000 , 3000 , 10_000 , 30_000 :
373
+ needle = 'ab' * N
374
+ haystack = ('ab' * (N - 1 ) + 'b' ) * 2
375
+ self .checkequal (- 1 , haystack , 'find' , needle )
376
+ self .checkequal (0 , haystack , 'count' , needle )
377
+ self .checkequal (len (haystack ), haystack + needle , 'find' , needle )
378
+ self .checkequal (1 , haystack + needle , 'count' , needle )
379
+
344
380
def test_find_shift_table_overflow (self ):
345
381
"""When the table of 8-bit shifts overflows."""
346
382
N = 2 ** 8 + 100
@@ -715,6 +751,18 @@ def test_replace(self):
715
751
self .checkraises (TypeError , 'hello' , 'replace' , 42 , 'h' )
716
752
self .checkraises (TypeError , 'hello' , 'replace' , 'h' , 42 )
717
753
754
+ def test_replace_uses_two_way_maxcount (self ):
755
+ # Test that maxcount works in _two_way_count in fastsearch.h
756
+ A , B = "A" * 1000 , "B" * 1000
757
+ AABAA = A + A + B + A + A
758
+ ABBA = A + B + B + A
759
+ self .checkequal (AABAA + ABBA ,
760
+ AABAA + ABBA , 'replace' , ABBA , "ccc" , 0 )
761
+ self .checkequal (AABAA + "ccc" ,
762
+ AABAA + ABBA , 'replace' , ABBA , "ccc" , 1 )
763
+ self .checkequal (AABAA + "ccc" ,
764
+ AABAA + ABBA , 'replace' , ABBA , "ccc" , 2 )
765
+
718
766
@unittest .skipIf (sys .maxsize > (1 << 32 ) or struct .calcsize ('P' ) != 4 ,
719
767
'only applies to 32-bit platforms' )
720
768
def test_replace_overflow (self ):
0 commit comments