@@ -312,6 +312,49 @@ let examples: [String] = _examples.flatMap { s in
312312 #endif
313313}
314314
315+
316+ suite. test ( " Trivial index conversion cases/characters " )
317+ . forEach ( in: examples) { s in
318+ for i in s. indices {
319+ let j = String . Index ( i, within: s)
320+ expectNotNil ( j, " i: \( i) " )
321+ expectEqual ( j, i)
322+ }
323+ }
324+
325+ suite. test ( " Trivial index conversion cases/scalars " )
326+ . forEach ( in: examples) { s in
327+ for i in s. unicodeScalars. indices {
328+ let j = String . Index ( i, within: s. unicodeScalars)
329+ expectNotNil ( j, " i: \( i) " )
330+ expectEqual ( j, i)
331+ }
332+ }
333+
334+ suite. test ( " Trivial index conversion cases/UTF-8 " )
335+ . forEach ( in: examples) { s in
336+ for i in s. utf8. indices {
337+ let j = String . Index ( i, within: s. utf8)
338+ expectNotNil ( j, " i: \( i) " )
339+ expectEqual ( j, i)
340+ }
341+ }
342+
343+ suite. test ( " Trivial index conversion cases/UTF-16 " )
344+ . forEach ( in: examples) { s in
345+ guard #available( SwiftStdlib 5 . 7 , * ) else {
346+ // Prior to 5.7, String.Index.init(_:within:) used to incorrectly reject
347+ // indices pointing to trailing surrogates.
348+ return
349+ }
350+
351+ for i in s. utf16. indices {
352+ let j = String . Index ( i, within: s. utf16)
353+ expectNotNil ( j, " i: \( i) " )
354+ expectEqual ( j, i)
355+ }
356+ }
357+
315358#if _runtime(_ObjC)
316359suite. test ( " Exhaustive Index Interchange " )
317360. forEach ( in: examples) { str in
@@ -712,7 +755,7 @@ suite.test("Global vs local grapheme cluster boundaries") {
712755}
713756
714757#if _runtime(_ObjC)
715- suite. test ( " Index encoding correction " ) {
758+ suite. test ( " Index encoding correction/subscripts " ) {
716759 guard #available( SwiftStdlib 5 . 7 , * ) else {
717760 // String indices did not track their encoding until 5.7.
718761 return
@@ -746,7 +789,7 @@ suite.test("Index encoding correction") {
746789 ( $0, s [ $0] , s. unicodeScalars [ $0] , s. utf8 [ $0] , s. utf16 [ $0] )
747790 }
748791
749- s. append ( " . " )
792+ s. makeContiguousUTF8 ( )
750793 //s.dumpIndices()
751794
752795 for (i, char, scalar, u8, u16) in originals {
@@ -758,6 +801,86 @@ suite.test("Index encoding correction") {
758801}
759802#endif
760803
804+ #if _runtime(_ObjC)
805+ suite. test ( " Index encoding correction/conversions/characters " ) {
806+ guard #available( SwiftStdlib 5 . 7 , * ) else {
807+ // String indices did not track their encoding until 5.7.
808+ return
809+ }
810+ var s = ( " 🫱🏼🫲🏽 a 🧑🏽🌾 b " as NSString ) as String
811+
812+ let chars = s. indices. map { ( $0, s [ $0] ) }
813+
814+ s. makeContiguousUTF8 ( )
815+
816+ for (i, char) in chars {
817+ let j = String . Index ( i, within: s)
818+ expectNotNil ( j, " i: \( i) " )
819+ expectEqual ( j. map { s [ $0] } , char, " i: \( i) " )
820+ }
821+ }
822+ #endif
823+
824+ #if _runtime(_ObjC)
825+ suite. test ( " Index encoding correction/conversions/scalars " ) {
826+ guard #available( SwiftStdlib 5 . 7 , * ) else {
827+ // String indices did not track their encoding until 5.7.
828+ return
829+ }
830+ var s = ( " 🫱🏼🫲🏽 a 🧑🏽🌾 b " as NSString ) as String
831+
832+ let scalars = s. unicodeScalars. indices. map { ( $0, s. unicodeScalars [ $0] ) }
833+
834+ s. makeContiguousUTF8 ( )
835+
836+ for (i, scalar) in scalars {
837+ let j = String . Index ( i, within: s. unicodeScalars)
838+ expectNotNil ( j, " i: \( i) " )
839+ expectEqual ( j. map { s. unicodeScalars [ $0] } , scalar, " i: \( i) " )
840+ }
841+ }
842+ #endif
843+
844+ #if _runtime(_ObjC)
845+ suite. test ( " Index encoding correction/conversions/UTF-8 " ) {
846+ guard #available( SwiftStdlib 5 . 7 , * ) else {
847+ // String indices did not track their encoding until 5.7.
848+ return
849+ }
850+ var s = ( " 🫱🏼🫲🏽 a 🧑🏽🌾 b " as NSString ) as String
851+
852+ let utf8Units = s. utf8. indices. map { ( $0, s. utf8 [ $0] ) }
853+
854+ s. makeContiguousUTF8 ( )
855+
856+ for (i, u8) in utf8Units {
857+ let j = String . Index ( i, within: s. utf8)
858+ expectNotNil ( j, " i: \( i) " )
859+ expectEqual ( j. map { s. utf8 [ $0] } , u8, " i: \( i) " )
860+ }
861+ }
862+ #endif
863+
864+ #if _runtime(_ObjC)
865+ suite. test ( " Index encoding correction/conversions/UTF-16 " ) {
866+ guard #available( SwiftStdlib 5 . 7 , * ) else {
867+ // String indices did not track their encoding until 5.7.
868+ return
869+ }
870+ var s = ( " 🫱🏼🫲🏽 a 🧑🏽🌾 b " as NSString ) as String
871+
872+ let utf16Units = s. utf16. indices. map { ( $0, s. utf16 [ $0] ) }
873+
874+ s. makeContiguousUTF8 ( )
875+
876+ for (i, u16) in utf16Units {
877+ let j = String . Index ( i, within: s. utf16)
878+ expectNotNil ( j, " i: \( i) " )
879+ expectEqual ( j. map { s. utf16 [ $0] } , u16, " i: \( i) " )
880+ }
881+ }
882+ #endif
883+
761884suite. test ( " String.replaceSubrange index validation " )
762885. forEach ( in: examples) { string in
763886 guard #available( SwiftStdlib 5 . 7 , * ) else {
0 commit comments