@@ -1124,3 +1124,90 @@ suite.test("Substring.removeSubrange entire range")
1124
1124
expectTrue ( b. isEmpty)
1125
1125
#endif
1126
1126
}
1127
+
1128
+ if #available( SwiftStdlib 5 . 8 , * ) {
1129
+ suite. test ( " String index rounding/Characters " )
1130
+ . forEach ( in: examples) { string in
1131
+ for index in string. allIndices ( includingEnd: true ) {
1132
+ let end = string. endIndex
1133
+ let expected = ( index < end
1134
+ ? string. indices. lastIndex { $0 <= index } !
1135
+ : end)
1136
+ let actual = string. _index ( roundingDown: index)
1137
+ expectEqual ( actual, expected,
1138
+ """
1139
+ index: \( index. _description)
1140
+ actual: \( actual. _description)
1141
+ expected: \( expected. _description)
1142
+ """ )
1143
+ }
1144
+ }
1145
+ }
1146
+
1147
+ suite. test ( " String index rounding/Scalars " )
1148
+ . forEach ( in: examples) { string in
1149
+ for index in string. allIndices ( includingEnd: true ) {
1150
+ let end = string. unicodeScalars. endIndex
1151
+ let expected = ( index < end
1152
+ ? string. unicodeScalars. indices. lastIndex { $0 <= index } !
1153
+ : end)
1154
+ let actual = string. unicodeScalars. _index ( roundingDown: index)
1155
+ expectEqual ( actual, expected,
1156
+ """
1157
+ index: \( index. _description)
1158
+ actual: \( actual. _description)
1159
+ expected: \( expected. _description)
1160
+ """ )
1161
+ }
1162
+ }
1163
+
1164
+ suite. test ( " String index rounding/UTF-16 " )
1165
+ . forEach ( in: examples) { string in
1166
+ //string.dumpIndices()
1167
+ var utf16Indices = Set ( string. utf16. indices)
1168
+ utf16Indices. insert ( string. utf16. endIndex)
1169
+
1170
+ for index in string. allIndices ( includingEnd: true ) {
1171
+ let expected : String . Index
1172
+ if utf16Indices. contains ( index) {
1173
+ expected = index
1174
+ } else {
1175
+ // If the index isn't valid in the UTF-16 view, it gets rounded down
1176
+ // to the nearest scalar boundary. (Unintuitively, this is generally *not*
1177
+ // the closest valid index within the UTF-16 view.)
1178
+ expected = string. unicodeScalars. indices. lastIndex { $0 <= index } !
1179
+ }
1180
+ let actual = string. utf16. _index ( roundingDown: index)
1181
+ expectEqual ( actual, expected,
1182
+ """
1183
+ index: \( index. _description)
1184
+ actual: \( actual. _description)
1185
+ expected: \( expected. _description)
1186
+ """ )
1187
+ }
1188
+ }
1189
+
1190
+ suite. test ( " String index rounding/UTF-8 " )
1191
+ . forEach ( in: examples) { string in
1192
+ //string.dumpIndices()
1193
+ var utf8Indices = Set ( string. utf8. indices)
1194
+ utf8Indices. insert ( string. utf8. endIndex)
1195
+ for index in string. allIndices ( includingEnd: true ) {
1196
+ let expected : String . Index
1197
+ if utf8Indices. contains ( index) {
1198
+ expected = index
1199
+ } else {
1200
+ // If the index isn't valid in the UTF-8 view, it gets rounded down
1201
+ // to the nearest scalar boundary. (Unintuitively, this is generally *not*
1202
+ // the closest valid index within the UTF-8 view.)
1203
+ expected = string. unicodeScalars. indices. lastIndex { $0 <= index } !
1204
+ }
1205
+ let actual = string. utf8. _index ( roundingDown: index)
1206
+ expectEqual ( actual, expected,
1207
+ """
1208
+ index: \( index. _description)
1209
+ actual: \( actual. _description)
1210
+ expected: \( expected. _description)
1211
+ """ )
1212
+ }
1213
+ }
0 commit comments