@@ -24,7 +24,7 @@ struct ComparisonTest {
24
24
init (
25
25
_ expectedUnicodeCollation: ExpectedComparisonResult ,
26
26
_ lhs: String , _ rhs: String ,
27
- xfail: TestRunPredicate = . custom ( { false } , reason : " " ) ,
27
+ xfail: TestRunPredicate = . never ,
28
28
file: String = #file, line: UInt = #line
29
29
) {
30
30
self . expectedUnicodeCollation = expectedUnicodeCollation
@@ -33,25 +33,28 @@ struct ComparisonTest {
33
33
self . loc = SourceLoc ( file, line, comment: " test data " )
34
34
self . xfail = xfail
35
35
}
36
+
37
+ func replacingPredicate( _ xfail: TestRunPredicate ) -> ComparisonTest {
38
+ return ComparisonTest ( expectedUnicodeCollation, lhs, rhs,
39
+ xfail: xfail, file: loc. file, line: loc. line)
40
+ }
36
41
}
37
42
38
- let comparisonTests = [
43
+ // List test cases for comparisons and prefix/suffix. Ideally none fail.
44
+
45
+ let tests = [
39
46
ComparisonTest ( . eq, " " , " " ) ,
40
47
ComparisonTest ( . lt, " " , " a " ) ,
41
48
42
49
// ASCII cases
43
50
ComparisonTest ( . lt, " t " , " tt " ) ,
44
- ComparisonTest ( . gt, " t " , " Tt " ,
45
- xfail: . nativeRuntime(
46
- " Compares in reverse with ICU, https://bugs.swift.org/browse/SR-530 " ) ) ,
47
- ComparisonTest ( . gt, " \u{0} " , " " ,
48
- xfail: . nativeRuntime(
49
- " Null-related issue: https://bugs.swift.org/browse/SR-630 " ) ) ,
51
+ ComparisonTest ( . gt, " t " , " Tt " ) ,
52
+ ComparisonTest ( . gt, " \u{0} " , " " ) ,
50
53
ComparisonTest ( . eq, " \u{0} " , " \u{0} " ) ,
51
- // Currently fails:
52
- // ComparisonTest(.lt, "\r\n", "t"),
53
- // ComparisonTest(.gt, "\r\n", "\n"),
54
- // ComparisonTest(.lt, "\u{0}", "\u{0}\u{0}"),
54
+
55
+ ComparisonTest ( . lt, " \r \n " , " t " ) ,
56
+ ComparisonTest ( . gt, " \r \n " , " \n " ) ,
57
+ ComparisonTest ( . lt, " \u{0} " , " \u{0} \u{0} " ) ,
55
58
56
59
// Whitespace
57
60
// U+000A LINE FEED (LF)
@@ -89,9 +92,7 @@ let comparisonTests = [
89
92
ComparisonTest ( . eq, " \u{212b} " , " A \u{30a} " ) ,
90
93
ComparisonTest ( . eq, " \u{212b} " , " \u{c5} " ) ,
91
94
ComparisonTest ( . eq, " A \u{30a} " , " \u{c5} " ) ,
92
- ComparisonTest ( . lt, " A \u{30a} " , " a " ,
93
- xfail: . nativeRuntime(
94
- " Compares in reverse with ICU, https://bugs.swift.org/browse/SR-530 " ) ) ,
95
+ ComparisonTest ( . lt, " A \u{30a} " , " a " ) ,
95
96
ComparisonTest ( . lt, " A " , " A \u{30a} " ) ,
96
97
97
98
// U+2126 OHM SIGN
@@ -114,6 +115,10 @@ let comparisonTests = [
114
115
ComparisonTest ( . eq, " \u{fb01} " , " \u{fb01} " ) ,
115
116
ComparisonTest ( . lt, " fi " , " \u{fb01} " ) ,
116
117
118
+ // U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B
119
+ // \u{1F1E7}\u{1F1E7} Flag of Barbados
120
+ ComparisonTest ( . lt, " \u{1F1E7} " , " \u{1F1E7} \u{1F1E7} " ) ,
121
+
117
122
// Test that Unicode collation is performed in deterministic mode.
118
123
//
119
124
// U+0301 COMBINING ACUTE ACCENT
@@ -128,10 +133,8 @@ let comparisonTests = [
128
133
// U+0301 and U+0954 don't decompose in the canonical decomposition mapping.
129
134
// U+0341 has a canonical decomposition mapping of U+0301.
130
135
ComparisonTest ( . eq, " \u{0301} " , " \u{0341} " ) ,
131
- ComparisonTest ( . lt, " \u{0301} " , " \u{0954} " ,
132
- xfail: . nativeRuntime( " Compares as equal with ICU " ) ) ,
133
- ComparisonTest ( . lt, " \u{0341} " , " \u{0954} " ,
134
- xfail: . nativeRuntime( " Compares as equal with ICU " ) ) ,
136
+ ComparisonTest ( . lt, " \u{0301} " , " \u{0954} " ) ,
137
+ ComparisonTest ( . lt, " \u{0341} " , " \u{0954} " ) ,
135
138
]
136
139
137
140
func checkStringComparison(
@@ -169,6 +172,28 @@ func checkStringComparison(
169
172
#endif
170
173
}
171
174
175
+ // Mark the test cases that are expected to fail in checkStringComparison
176
+
177
+ let comparisonTests = tests. map {
178
+ ( test: ComparisonTest ) -> ComparisonTest in
179
+ switch ( test. expectedUnicodeCollation, test. lhs, test. rhs) {
180
+ case ( . gt, " t " , " Tt " ) , ( . lt, " A \u{30a} " , " a " ) :
181
+ return test. replacingPredicate ( . nativeRuntime(
182
+ " Comparison reversed between ICU and CFString, https://bugs.swift.org/browse/SR-530 " ) )
183
+
184
+ case ( . gt, " \u{0} " , " " ) , ( . lt, " \u{0} " , " \u{0} \u{0} " ) :
185
+ return test. replacingPredicate ( . nativeRuntime(
186
+ " Null-related issue: https://bugs.swift.org/browse/SR-630 " ) )
187
+
188
+ case ( . lt, " \u{0301} " , " \u{0954} " ) , ( . lt, " \u{0341} " , " \u{0954} " ) :
189
+ return test. replacingPredicate ( . nativeRuntime(
190
+ " Compares as equal with ICU " ) )
191
+
192
+ default :
193
+ return test
194
+ }
195
+ }
196
+
172
197
for test in comparisonTests {
173
198
StringTests . test ( " String.{Equatable,Hashable,Comparable}: line \( test. loc. line) " )
174
199
. xfail ( test. xfail)
@@ -257,11 +282,38 @@ StringTests.test("LosslessStringConvertible") {
257
282
checkLosslessStringConvertible ( comparisonTests. map { $0. rhs } )
258
283
}
259
284
260
- StringTests . test ( " hasPrefix,hasSuffix " )
261
- . skip ( . nativeRuntime(
262
- " String.has{Prefix,Suffix} defined when _runtime(_ObjC) " ) )
263
- . code {
264
- for test in comparisonTests {
285
+ // Mark the test cases that are expected to fail in checkHasPrefixHasSuffix
286
+
287
+ let substringTests = tests. map {
288
+ ( test: ComparisonTest ) -> ComparisonTest in
289
+ switch ( test. expectedUnicodeCollation, test. lhs, test. rhs) {
290
+ case ( . eq, " \u{0} " , " \u{0} " ) :
291
+ return test. replacingPredicate ( . objCRuntime(
292
+ " https://bugs.swift.org/browse/SR-332 " ) )
293
+
294
+ case ( . gt, " \r \n " , " \n " ) :
295
+ return test. replacingPredicate ( . objCRuntime(
296
+ " blocked on rdar://problem/19036555 " ) )
297
+
298
+ case ( . eq, " \u{0301} " , " \u{0341} " ) :
299
+ return test. replacingPredicate ( . objCRuntime(
300
+ " https://bugs.swift.org/browse/SR-243 " ) )
301
+
302
+ case ( . lt, " \u{1F1E7} " , " \u{1F1E7} \u{1F1E7} " ) :
303
+ return test. replacingPredicate ( . objCRuntime(
304
+ " https://bugs.swift.org/browse/SR-367 " ) )
305
+
306
+ default :
307
+ return test
308
+ }
309
+ }
310
+
311
+ for test in substringTests {
312
+ StringTests . test ( " hasPrefix,hasSuffix: line \( test. loc. line) " )
313
+ . skip ( . nativeRuntime(
314
+ " String.has{Prefix,Suffix} defined when _runtime(_ObjC) " ) )
315
+ . xfail ( test. xfail)
316
+ . code {
265
317
checkHasPrefixHasSuffix ( test. lhs, test. rhs, test. loc. withCurrentLoc ( ) )
266
318
checkHasPrefixHasSuffix ( test. rhs, test. lhs, test. loc. withCurrentLoc ( ) )
267
319
@@ -275,26 +327,6 @@ StringTests.test("hasPrefix,hasSuffix")
275
327
}
276
328
}
277
329
278
- StringTests . test ( " Failures{hasPrefix,hasSuffix}-CF " )
279
- . skip ( . nativeRuntime(
280
- " String.has{Prefix,Suffix} defined when _runtime(_ObjC) " ) )
281
- . code {
282
- let test = ComparisonTest ( . lt, " \u{0} " , " \u{0} \u{0} " )
283
- checkHasPrefixHasSuffix ( test. lhs, test. rhs, test. loc. withCurrentLoc ( ) )
284
- }
285
-
286
- StringTests . test ( " Failures{hasPrefix,hasSuffix} " )
287
- . xfail ( . custom( { true } , reason: " blocked on rdar://problem/19036555 " ) )
288
- . skip ( . nativeRuntime(
289
- " String.has{Prefix,Suffix} defined when _runtime(_ObjC) " ) )
290
- . code {
291
- let tests =
292
- [ ComparisonTest ( . lt, " \r \n " , " t " ) , ComparisonTest ( . gt, " \r \n " , " \n " ) ]
293
- tests. forEach {
294
- checkHasPrefixHasSuffix ( $0. lhs, $0. rhs, $0. loc. withCurrentLoc ( ) )
295
- }
296
- }
297
-
298
330
StringTests . test ( " SameTypeComparisons " ) {
299
331
// U+0323 COMBINING DOT BELOW
300
332
// U+0307 COMBINING DOT ABOVE
@@ -312,8 +344,7 @@ StringTests.test("SameTypeComparisons") {
312
344
313
345
StringTests . test ( " CompareStringsWithUnpairedSurrogates " )
314
346
. xfail (
315
- . custom( { true } ,
316
- reason: " <rdar://problem/18029104> Strings referring to underlying " +
347
+ . always( " <rdar://problem/18029104> Strings referring to underlying " +
317
348
" storage with unpaired surrogates compare unequal " ) )
318
349
. code {
319
350
let donor = " abcdef "
0 commit comments