@@ -572,6 +572,44 @@ class AlgorithmTests: XCTestCase {
572
572
s2. matches ( of: try Regex ( " a*? " ) ) . map { s2. offsets ( of: $0. range) } , [ 0 ..< 0 , 1 ..< 1 , 2 ..< 2 ] )
573
573
XCTAssertEqual (
574
574
s2. ranges ( of: try Regex ( " a*? " ) ) . map ( s2. offsets ( of: ) ) , [ 0 ..< 0 , 1 ..< 1 , 2 ..< 2 ] )
575
+
576
+ func checkContains(
577
+ _ expected: Bool ,
578
+ _ a: some StringProtocol ,
579
+ _ b: some StringProtocol ,
580
+ file: StaticString = #file, line: UInt = #line
581
+ ) {
582
+ let result = a. firstRange ( of: b) != nil
583
+ XCTAssertEqual ( expected, result, file: file, line: line)
584
+ }
585
+
586
+ // Make sure that searching doesn't match over a substring boundary, even
587
+ // when the boundary is in the middle of a character.
588
+ let cafe = " c \u{302} afe \u{301} "
589
+ let cafeStringDropLastScalar = " c \u{302} afe "
590
+ let cafeStringDropFirstScalar = " \u{302} afe \u{301} "
591
+ let cafeSubDropLastScalar =
592
+ cafe [ ..< ( cafe. unicodeScalars. index ( before: cafe. endIndex) ) ]
593
+ let cafeSubDropFirstScalar =
594
+ cafe [ cafe. unicodeScalars. index ( after: cafe. startIndex) ... ]
595
+
596
+ checkContains ( false , cafe, cafeStringDropLastScalar)
597
+ checkContains ( false , cafe, cafeStringDropFirstScalar)
598
+ checkContains ( false , cafe, cafeSubDropLastScalar)
599
+ checkContains ( false , cafe, cafeSubDropFirstScalar)
600
+ checkContains ( false , cafe, " afe " )
601
+ checkContains ( true , cafe, " afé " )
602
+ checkContains ( true , cafe, " ĉaf " )
603
+
604
+ checkContains ( false , cafeSubDropLastScalar, " afe \u{301} " )
605
+ checkContains ( false , cafeSubDropLastScalar, " afé " )
606
+ checkContains ( true , cafeSubDropLastScalar, " afe " )
607
+ checkContains ( true , cafeSubDropLastScalar, cafeStringDropLastScalar)
608
+
609
+ checkContains ( false , cafeSubDropFirstScalar, " c \u{302} af " )
610
+ checkContains ( false , cafeSubDropFirstScalar, " ĉaf " )
611
+ checkContains ( true , cafeSubDropFirstScalar, " \u{302} af " )
612
+ checkContains ( true , cafeSubDropFirstScalar, cafeStringDropFirstScalar)
575
613
}
576
614
577
615
func testUnicodeScalarSemantics( ) throws {
0 commit comments