Skip to content

Commit 33856e7

Browse files
authored
Merge pull request #559 from hamishknight/validate-test
2 parents 3683457 + 9212b43 commit 33856e7

File tree

1 file changed

+42
-40
lines changed

1 file changed

+42
-40
lines changed

Tests/RegexTests/MatchTests.swift

+42-40
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,33 @@ func _firstMatch(
2525
input: String,
2626
validateOptimizations: Bool,
2727
syntax: SyntaxOptions = .traditional
28-
) throws -> (String, [String?]) {
28+
) throws -> (String, [String?])? {
2929
var regex = try Regex(regexStr, syntax: syntax)
30-
guard let result = try regex.firstMatch(in: input) else {
31-
throw MatchError("match not found for \(regexStr) in \(input)")
32-
}
33-
let caps = result.output.slices(from: input)
34-
30+
let result = try regex.firstMatch(in: input)
31+
3532
if validateOptimizations {
3633
regex._setCompilerOptionsForTesting(.disableOptimizations)
37-
guard let unoptResult = try regex.firstMatch(in: input) else {
34+
let unoptResult = try regex.firstMatch(in: input)
35+
if result != nil && unoptResult == nil {
3836
throw MatchError("match not found for unoptimized \(regexStr) in \(input)")
3937
}
40-
XCTAssertEqual(
41-
String(input[result.range]),
42-
String(input[unoptResult.range]),
43-
"Unoptimized regex returned a different result")
38+
if result == nil && unoptResult != nil {
39+
throw MatchError("match not found in optimized \(regexStr) in \(input)")
40+
}
41+
if let result = result, let unoptResult = unoptResult {
42+
let optMatch = String(input[result.range])
43+
let unoptMatch = String(input[unoptResult.range])
44+
if optMatch != unoptMatch {
45+
throw MatchError("""
46+
47+
Unoptimized regex returned: '\(unoptMatch)'
48+
Optimized regex returned: '\(optMatch)'
49+
""")
50+
}
51+
}
4452
}
53+
guard let result = result else { return nil }
54+
let caps = result.output.slices(from: input)
4555
return (String(input[result.range]), caps.map { $0.map(String.init) })
4656
}
4757

@@ -147,21 +157,19 @@ func firstMatchTest(
147157
line: UInt = #line
148158
) {
149159
do {
150-
let (found, _) = try _firstMatch(
160+
let found = try _firstMatch(
151161
regex,
152162
input: input,
153163
validateOptimizations: validateOptimizations,
154-
syntax: syntax)
164+
syntax: syntax)?.0
155165

156166
if xfail {
157167
XCTAssertNotEqual(found, match, file: file, line: line)
158168
} else {
159169
XCTAssertEqual(found, match, file: file, line: line)
160170
}
161171
} catch {
162-
// FIXME: This allows non-matches to succeed even when xfail'd
163-
// When xfail == true, this should report failure for match == nil
164-
if !xfail && match != nil {
172+
if !xfail {
165173
XCTFail("\(error)", file: file, line: line)
166174
}
167175
return
@@ -421,8 +429,7 @@ extension RegexTests {
421429
"a++a",
422430
("babc", nil),
423431
("baaabc", nil),
424-
("bb", nil),
425-
xfail: true)
432+
("bb", nil))
426433
firstMatchTests(
427434
"a+?a",
428435
("babc", nil),
@@ -498,23 +505,19 @@ extension RegexTests {
498505
("baabc", nil),
499506
("bb", nil))
500507

501-
// XFAIL'd versions of the above
502508
firstMatchTests(
503509
"a{2,4}+a",
504-
("baaabc", nil),
505-
xfail: true)
510+
("baaabc", nil))
506511
firstMatchTests(
507512
"a{,4}+a",
508513
("babc", nil),
509514
("baabc", nil),
510-
("baaabc", nil),
511-
xfail: true)
515+
("baaabc", nil))
512516
firstMatchTests(
513517
"a{2,}+a",
514518
("baaabc", nil),
515519
("baaaaabc", nil),
516-
("baaaaaaaabc", nil),
517-
xfail: true)
520+
("baaaaaaaabc", nil))
518521

519522
// XFAIL'd possessive tests
520523
firstMatchTests(
@@ -709,6 +712,11 @@ extension RegexTests {
709712
}
710713
firstMatchTest(#"[\t-\t]"#, input: "\u{8}\u{A}\u{9}", match: "\u{9}")
711714

715+
// FIXME: This produces a different result with and without optimizations.
716+
firstMatchTest(#"[1-2]"#, input: "1️⃣", match: nil, xfail: true)
717+
firstMatchTest(#"[1-2]"#, input: "1️⃣", match: nil,
718+
validateOptimizations: false)
719+
712720
// Currently not supported in the matching engine.
713721
for c: UnicodeScalar in ["a", "b", "c"] {
714722
firstMatchTest(#"[\c!-\C-#]"#, input: "def\(c)", match: "\(c)",
@@ -1054,8 +1062,8 @@ extension RegexTests {
10541062
// TODO: Oniguruma \y and \Y
10551063
firstMatchTests(
10561064
#"\u{65}"#, // Scalar 'e' is present in both
1057-
("Cafe\u{301}", nil), // but scalar mode requires boundary at end of match
1058-
xfail: true)
1065+
("Cafe\u{301}", nil)) // but scalar mode requires boundary at end of match
1066+
10591067
firstMatchTests(
10601068
#"\u{65}"#, // Scalar 'e' is present in both
10611069
("Sol Cafe", "e")) // standalone is okay
@@ -1647,19 +1655,15 @@ extension RegexTests {
16471655
firstMatchTest(#"\u{65 301}$"#, input: eComposed, match: eComposed)
16481656

16491657
// FIXME: Implicit \y at end of match
1650-
firstMatchTest(#"\u{65}"#, input: eDecomposed, match: nil,
1651-
xfail: true)
1658+
firstMatchTest(#"\u{65}"#, input: eDecomposed, match: nil)
16521659
firstMatchTest(#"\u{65}$"#, input: eDecomposed, match: nil)
1653-
// FIXME: \y is unsupported
1654-
firstMatchTest(#"\u{65}\y"#, input: eDecomposed, match: nil,
1655-
xfail: true)
1660+
firstMatchTest(#"\u{65}\y"#, input: eDecomposed, match: nil)
16561661

16571662
// FIXME: Unicode scalars are only matched at the start of a grapheme cluster
16581663
firstMatchTest(#"\u{301}"#, input: eDecomposed, match: "\u{301}",
16591664
xfail: true)
1660-
// FIXME: \y is unsupported
1661-
firstMatchTest(#"\y\u{301}"#, input: eDecomposed, match: nil,
1662-
xfail: true)
1665+
1666+
firstMatchTest(#"\y\u{301}"#, input: eDecomposed, match: nil)
16631667
}
16641668

16651669
func testCanonicalEquivalence() throws {
@@ -1717,13 +1721,11 @@ extension RegexTests {
17171721
// \s
17181722
firstMatchTest(#"\s"#, input: " ", match: " ")
17191723
// FIXME: \s shouldn't match a number composed with a non-number character
1720-
firstMatchTest(#"\s\u{305}"#, input: " ", match: nil,
1721-
xfail: true)
1724+
firstMatchTest(#"\s\u{305}"#, input: " ", match: nil)
17221725
// \p{Whitespace}
17231726
firstMatchTest(#"\s"#, input: " ", match: " ")
1724-
// FIXME: \p{Whitespace} shouldn't match whitespace composed with a non-whitespace character
1725-
firstMatchTest(#"\s\u{305}"#, input: " ", match: nil,
1726-
xfail: true)
1727+
// \p{Whitespace} shouldn't match whitespace composed with a non-whitespace character
1728+
firstMatchTest(#"\s\u{305}"#, input: " ", match: nil)
17271729
}
17281730

17291731
func testCanonicalEquivalenceCustomCharacterClass() throws {

0 commit comments

Comments
 (0)