@@ -1086,3 +1086,90 @@ suite.test("Substring.removeSubrange entire range")
1086
1086
expectTrue ( b. isEmpty)
1087
1087
#endif
1088
1088
}
1089
+
1090
+ if #available( SwiftStdlib 5 . 8 , * ) {
1091
+ suite. test ( " String index rounding/Characters " )
1092
+ . forEach ( in: examples) { string in
1093
+ for index in string. allIndices ( includingEnd: true ) {
1094
+ let end = string. endIndex
1095
+ let expected = ( index < end
1096
+ ? string. indices. lastIndex { $0 <= index } !
1097
+ : end)
1098
+ let actual = string. _index ( roundingDown: index)
1099
+ expectEqual ( actual, expected,
1100
+ """
1101
+ index: \( index. _description)
1102
+ actual: \( actual. _description)
1103
+ expected: \( expected. _description)
1104
+ """ )
1105
+ }
1106
+ }
1107
+ }
1108
+
1109
+ suite. test ( " String index rounding/Scalars " )
1110
+ . forEach ( in: examples) { string in
1111
+ for index in string. allIndices ( includingEnd: true ) {
1112
+ let end = string. unicodeScalars. endIndex
1113
+ let expected = ( index < end
1114
+ ? string. unicodeScalars. indices. lastIndex { $0 <= index } !
1115
+ : end)
1116
+ let actual = string. unicodeScalars. _index ( roundingDown: index)
1117
+ expectEqual ( actual, expected,
1118
+ """
1119
+ index: \( index. _description)
1120
+ actual: \( actual. _description)
1121
+ expected: \( expected. _description)
1122
+ """ )
1123
+ }
1124
+ }
1125
+
1126
+ suite. test ( " String index rounding/UTF-16 " )
1127
+ . forEach ( in: examples) { string in
1128
+ //string.dumpIndices()
1129
+ var utf16Indices = Set ( string. utf16. indices)
1130
+ utf16Indices. insert ( string. utf16. endIndex)
1131
+
1132
+ for index in string. allIndices ( includingEnd: true ) {
1133
+ let expected : String . Index
1134
+ if utf16Indices. contains ( index) {
1135
+ expected = index
1136
+ } else {
1137
+ // If the index isn't valid in the UTF-16 view, it gets rounded down
1138
+ // to the nearest scalar boundary. (Unintuitively, this is generally *not*
1139
+ // the closest valid index within the UTF-16 view.)
1140
+ expected = string. unicodeScalars. indices. lastIndex { $0 <= index } !
1141
+ }
1142
+ let actual = string. utf16. _index ( roundingDown: index)
1143
+ expectEqual ( actual, expected,
1144
+ """
1145
+ index: \( index. _description)
1146
+ actual: \( actual. _description)
1147
+ expected: \( expected. _description)
1148
+ """ )
1149
+ }
1150
+ }
1151
+
1152
+ suite. test ( " String index rounding/UTF-8 " )
1153
+ . forEach ( in: examples) { string in
1154
+ //string.dumpIndices()
1155
+ var utf8Indices = Set ( string. utf8. indices)
1156
+ utf8Indices. insert ( string. utf8. endIndex)
1157
+ for index in string. allIndices ( includingEnd: true ) {
1158
+ let expected : String . Index
1159
+ if utf8Indices. contains ( index) {
1160
+ expected = index
1161
+ } else {
1162
+ // If the index isn't valid in the UTF-8 view, it gets rounded down
1163
+ // to the nearest scalar boundary. (Unintuitively, this is generally *not*
1164
+ // the closest valid index within the UTF-8 view.)
1165
+ expected = string. unicodeScalars. indices. lastIndex { $0 <= index } !
1166
+ }
1167
+ let actual = string. utf8. _index ( roundingDown: index)
1168
+ expectEqual ( actual, expected,
1169
+ """
1170
+ index: \( index. _description)
1171
+ actual: \( actual. _description)
1172
+ expected: \( expected. _description)
1173
+ """ )
1174
+ }
1175
+ }
0 commit comments