@@ -155,6 +155,32 @@ func rangeTest(
155
155
}
156
156
}
157
157
158
+ func diagnosticTest(
159
+ _ input: String , _ expected: ParseError ,
160
+ syntax: SyntaxOptions = . traditional,
161
+ file: StaticString = #file, line: UInt = #line
162
+ ) {
163
+ do {
164
+ let ast = try parse ( input, syntax)
165
+ XCTFail ( """
166
+
167
+ Passed \( ast)
168
+ But expected error: \( expected)
169
+ """ , file: file, line: line)
170
+ } catch let e as Source . LocatedError < ParseError > {
171
+ guard e. error == expected else {
172
+ XCTFail ( """
173
+
174
+ Expected: \( expected)
175
+ Actual: \( e. error)
176
+ """ , file: file, line: line)
177
+ return
178
+ }
179
+ } catch let e {
180
+ XCTFail ( " Error without source location: \( e) " , file: file, line: line)
181
+ }
182
+ }
183
+
158
184
extension RegexTests {
159
185
func testParse( ) {
160
186
parseTest (
@@ -435,7 +461,7 @@ extension RegexTests {
435
461
436
462
// Quotes in character classes.
437
463
parseTest ( #"[\Q-\E]"# , charClass ( quote_m ( " - " ) ) )
438
- parseTest ( #"[\Qa-b[[*+\\E]"# , charClass ( quote_m ( # "a-b[[*+\"# ) ) )
464
+ parseTest ( #"[\Qa-b[[*+\\E]"# , charClass ( quote_m ( " a-b[[*+ \\ " ) ) )
439
465
440
466
parseTest ( #"["-"]"# , charClass ( quote_m ( " - " ) ) , syntax: . experimental)
441
467
parseTest ( #"["a-b[[*+\""]"# , charClass ( quote_m ( #"a-b[[*+""# ) ) ,
@@ -1038,17 +1064,59 @@ extension RegexTests {
1038
1064
}
1039
1065
1040
1066
func testParseErrors( ) {
1067
+ // MARK: Closing delimiters.
1041
1068
1042
- func performErrorTest( _ input: String , _ expecting: String ) {
1043
- // // Quick pattern match against AST to extract error nodes
1044
- // let ast = parse2(input)
1045
- // print(ast)
1046
- }
1069
+ diagnosticTest ( " ( " , . expected( " ) " ) )
1047
1070
1048
- performErrorTest ( " ( " , " " )
1071
+ diagnosticTest ( #"\u{5"# , . expected( " } " ) )
1072
+ diagnosticTest ( #"\x{5"# , . expected( " } " ) )
1073
+ diagnosticTest ( #"\N{A"# , . expected( " } " ) )
1074
+ diagnosticTest ( #"\N{U+A"# , . expected( " } " ) )
1075
+ diagnosticTest ( #"\p{a"# , . expected( " } " ) )
1076
+ diagnosticTest ( #"\p{a="# , . expected( " } " ) )
1077
+ diagnosticTest ( #"(?#"# , . expected( " ) " ) )
1078
+ diagnosticTest ( #"(?x"# , . expected( " ) " ) )
1049
1079
1080
+ diagnosticTest ( #"(?"# , . expectedGroupSpecifier)
1081
+ diagnosticTest ( #"(?^"# , . expected( " ) " ) )
1082
+ diagnosticTest ( #"(?^i"# , . expected( " ) " ) )
1050
1083
1051
- }
1084
+ diagnosticTest ( #"(?y)"# , . expected( " { " ) )
1085
+ diagnosticTest ( #"(?y{)"# , . expected( " g " ) )
1086
+ diagnosticTest ( #"(?y{g)"# , . expected( " } " ) )
1087
+ diagnosticTest ( #"(?y{x})"# , . expected( " g " ) )
1052
1088
1053
- }
1089
+ diagnosticTest ( #"(?P"# , . expected( " ) " ) )
1090
+ diagnosticTest ( #"(?R"# , . expected( " ) " ) )
1054
1091
1092
+ diagnosticTest ( #"\Qab"# , . expected( " \\ E " ) )
1093
+ diagnosticTest ( " \\ Qab \\ " , . expected( " \\ E " ) )
1094
+ diagnosticTest ( #""ab"# , . expected( " \" " ) , syntax: . experimental)
1095
+ diagnosticTest ( #""ab\""# , . expected( " \" " ) , syntax: . experimental)
1096
+
1097
+ // MARK: Text Segment options
1098
+
1099
+ diagnosticTest ( " (?-y{g}) " , . cannotRemoveTextSegmentOptions)
1100
+ diagnosticTest ( " (?-y{w}) " , . cannotRemoveTextSegmentOptions)
1101
+
1102
+ // MARK: Group specifiers
1103
+
1104
+ diagnosticTest ( #"(*"# , . misc( " Quantifier '*' must follow operand " ) )
1105
+
1106
+ diagnosticTest ( #"(?k)"# , . unknownGroupKind( " ?k " ) )
1107
+ diagnosticTest ( #"(?P#)"# , . invalidMatchingOption( " # " ) )
1108
+
1109
+ // MARK: Matching options
1110
+
1111
+ diagnosticTest ( #"(?^-"# , . cannotRemoveMatchingOptionsAfterCaret)
1112
+ diagnosticTest ( #"(?^-)"# , . cannotRemoveMatchingOptionsAfterCaret)
1113
+ diagnosticTest ( #"(?^i-"# , . cannotRemoveMatchingOptionsAfterCaret)
1114
+ diagnosticTest ( #"(?^i-m)"# , . cannotRemoveMatchingOptionsAfterCaret)
1115
+
1116
+ // MARK: Quotes
1117
+
1118
+ diagnosticTest ( #"\k''"# , . expectedNonEmptyContents)
1119
+ diagnosticTest ( #"(?&)"# , . expectedNonEmptyContents)
1120
+ diagnosticTest ( #"(?P>)"# , . expectedNonEmptyContents)
1121
+ }
1122
+ }
0 commit comments