Skip to content

Commit 318277c

Browse files
committed
[test] stdlib/StringIndex: Spin off O(n^4) substring replacement test into a standalone long test
Also trim down its input a bit so that this doesn’t take 20 minutes.
1 parent 8d8c652 commit 318277c

File tree

2 files changed

+103
-77
lines changed

2 files changed

+103
-77
lines changed

test/stdlib/StringIndex.swift

-77
Original file line numberDiff line numberDiff line change
@@ -822,80 +822,3 @@ suite.test("String.replaceSubrange index validation")
822822
}
823823
}
824824
}
825-
826-
suite.test("Substring.replaceSubrange index validation")
827-
.forEach(in: examples) { string in
828-
guard #available(SwiftStdlib 5.7, *) else {
829-
// Index navigation in 5.7 always rounds input indices down to the nearest
830-
// Character, so that we always have a well-defined distance between
831-
// indices, even if they aren't valid.
832-
//
833-
// 5.6 and below did not behave consistently in this case.
834-
return
835-
}
836-
837-
string.dumpIndices()
838-
839-
let scalarMap = string.scalarMap()
840-
let allIndices = string.allIndices()
841-
842-
for i in allIndices {
843-
print(i)
844-
for j in allIndices {
845-
guard i <= j else { continue }
846-
let si = scalarMap[i]!.index
847-
let sj = scalarMap[j]!.index
848-
849-
let substring = string[i ..< j]
850-
851-
let subindices = substring.allIndices()
852-
for m in subindices {
853-
for n in subindices {
854-
guard m <= n else { continue }
855-
let sm = scalarMap[m]!.index
856-
let sn = scalarMap[n]!.index
857-
858-
let replacement = "x"
859-
860-
var _expected = "".unicodeScalars
861-
_expected += string.unicodeScalars[si ..< sm]
862-
_expected += replacement.unicodeScalars
863-
_expected += string.unicodeScalars[sn ..< sj]
864-
let expected = String(_expected)[...]
865-
866-
// Check Substring.replaceSubrange(_:with:)
867-
do {
868-
var actual = substring
869-
actual.replaceSubrange(m ..< n, with: Array(replacement))
870-
871-
expectEqual(actual, expected,
872-
"""
873-
string: \(string.debugDescription)
874-
i: \(i)
875-
j: \(j)
876-
m: \(m)
877-
n: \(n)
878-
""")
879-
}
880-
881-
// Check String.unicodeScalars.replaceSubrange(_:with:)
882-
do {
883-
var actual = substring
884-
actual.unicodeScalars.replaceSubrange(
885-
m ..< n, with: Array(replacement.unicodeScalars))
886-
887-
expectEqual(actual, expected,
888-
"""
889-
string: \(string.debugDescription)
890-
i: \(i)
891-
j: \(j)
892-
m: \(m)
893-
n: \(n)
894-
""")
895-
}
896-
}
897-
}
898-
}
899-
}
900-
}
901-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// RUN: %target-run-simple-swift
2+
// REQUIRES: executable_test
3+
// REQUIRES: long_test
4+
5+
import StdlibUnittest
6+
#if _runtime(_ObjC)
7+
import Foundation
8+
#endif
9+
10+
var suite = TestSuite("StringIndexLong")
11+
defer { runAllTests() }
12+
13+
let _examples: [StaticString] = [
14+
"abc\r\ndefg",
15+
"a\r\ncдe\u{301}日🧟‍♀️x🏳️‍🌈🇺🇸🇨🇦",
16+
]
17+
18+
let examples: [String] = _examples.flatMap { s in
19+
let str = "\(s)"
20+
#if _runtime(_ObjC)
21+
let unichars = Array(str.utf16)
22+
let nsstr = NSString(characters: unichars, length: unichars.count)
23+
return [str, nsstr as String]
24+
#else
25+
return [str]
26+
#endif
27+
}
28+
29+
suite.test("Substring.replaceSubrange index validation")
30+
.forEach(in: examples) { string in
31+
guard #available(SwiftStdlib 5.7, *) else {
32+
// Index navigation in 5.7 always rounds input indices down to the nearest
33+
// Character, so that we always have a well-defined distance between
34+
// indices, even if they aren't valid.
35+
//
36+
// 5.6 and below did not behave consistently in this case.
37+
return
38+
}
39+
40+
string.dumpIndices()
41+
42+
let scalarMap = string.scalarMap()
43+
let allIndices = string.allIndices()
44+
45+
for i in allIndices {
46+
print(i)
47+
for j in allIndices {
48+
guard i <= j else { continue }
49+
let si = scalarMap[i]!.index
50+
let sj = scalarMap[j]!.index
51+
52+
let substring = string[i ..< j]
53+
54+
let subindices = substring.allIndices()
55+
for m in subindices {
56+
for n in subindices {
57+
guard m <= n else { continue }
58+
let sm = scalarMap[m]!.index
59+
let sn = scalarMap[n]!.index
60+
61+
let replacement = "x"
62+
63+
var _expected = "".unicodeScalars
64+
_expected += string.unicodeScalars[si ..< sm]
65+
_expected += replacement.unicodeScalars
66+
_expected += string.unicodeScalars[sn ..< sj]
67+
let expected = String(_expected)[...]
68+
69+
// Check Substring.replaceSubrange(_:with:)
70+
do {
71+
var actual = substring
72+
actual.replaceSubrange(m ..< n, with: Array(replacement))
73+
74+
expectEqual(actual, expected,
75+
"""
76+
string: \(string.debugDescription)
77+
i: \(i)
78+
j: \(j)
79+
m: \(m)
80+
n: \(n)
81+
""")
82+
}
83+
84+
// Check String.unicodeScalars.replaceSubrange(_:with:)
85+
do {
86+
var actual = substring
87+
actual.unicodeScalars.replaceSubrange(
88+
m ..< n, with: Array(replacement.unicodeScalars))
89+
90+
expectEqual(actual, expected,
91+
"""
92+
string: \(string.debugDescription)
93+
i: \(i)
94+
j: \(j)
95+
m: \(m)
96+
n: \(n)
97+
""")
98+
}
99+
}
100+
}
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)