10
10
//
11
11
//===----------------------------------------------------------------------===//
12
12
13
+ import SKTestSupport
13
14
@_spi ( Testing) import SourceKitLSP
14
15
import SwiftParser
15
16
import SwiftRefactor
@@ -20,7 +21,7 @@ final class SyntaxRefactorTests: XCTestCase {
20
21
func testAddDocumentationRefactor( ) throws {
21
22
try assertRefactor (
22
23
"""
23
- func refactor (syntax: DeclSyntax, in context: Void) -> DeclSyntax? { }
24
+ 1️⃣func 2️⃣refactor (syntax: DeclSyntax, in context: Void) -> DeclSyntax? { }
24
25
""" ,
25
26
context: ( ) ,
26
27
provider: AddDocumentation . self,
@@ -43,21 +44,21 @@ final class SyntaxRefactorTests: XCTestCase {
43
44
44
45
func testConvertJSONToCodableStructClosure( ) throws {
45
46
try assertRefactor (
46
- malformedInput : """
47
- {
48
- " name " : " Produce " ,
49
- " shelves " : [
50
- {
51
- " name " : " Discount Produce " ,
52
- " product " : {
53
- " name " : " Banana " ,
54
- " points " : 200,
55
- " description " : " A banana that's perfectly ripe. "
56
- }
57
- }
58
- ]
59
- }
60
- """ ,
47
+ """
48
+ 4️⃣{1️⃣
49
+ 2️⃣ " name " : " Produce " ,
50
+ " shelves " : [
51
+ {
52
+ " name " : " Discount Produce " ,
53
+ " product " : {
54
+ " name " : " Banana " ,
55
+ " points " : 200,
56
+ " description " : " A banana that's perfectly ripe. "
57
+ }
58
+ }
59
+ ]
60
+ }
61
+ """ ,
61
62
context: ( ) ,
62
63
provider: ConvertJSONToCodableStruct . self,
63
64
expected: [
@@ -87,23 +88,23 @@ final class SyntaxRefactorTests: XCTestCase {
87
88
88
89
func testConvertJSONToCodableStructLiteral( ) throws {
89
90
try assertRefactor (
90
- malformedInput: #"""
91
+ #"""
92
+ """
93
+ {
94
+ "name": "Produce",
95
+ "shelves": [
96
+ {
97
+ "name": "Discount Produce",
98
+ "product": {
99
+ "name": "Banana",
100
+ "points": 200,
101
+ "description": "A banana that's perfectly ripe."
102
+ }
103
+ }
104
+ ]
105
+ }
91
106
"""
92
- {
93
- "name": "Produce",
94
- "shelves": [
95
- {
96
- "name": "Discount Produce",
97
- "product": {
98
- "name": "Banana",
99
- "points": 200,
100
- "description": "A banana that's perfectly ripe."
101
- }
102
- }
103
- ]
104
- }
105
- """
106
- """# ,
107
+ """# ,
107
108
context: ( ) ,
108
109
provider: ConvertJSONToCodableStruct . self,
109
110
expected: [
@@ -134,44 +135,44 @@ final class SyntaxRefactorTests: XCTestCase {
134
135
135
136
func testConvertJSONToCodableStructClosureMerging( ) throws {
136
137
try assertRefactor (
137
- malformedInput : """
138
- {
139
- " name " : " Store " ,
140
- " shelves " : [
141
- {
142
- " name " : " Discount Produce " ,
143
- " product " : {
144
- " name " : " Banana " ,
145
- " points " : 200,
146
- " description " : " A banana that's perfectly ripe. " ,
147
- " healthy " : " true " ,
148
- " delicious " : " true " ,
149
- " categories " : [ " fruit " , " yellow " ]
150
- }
151
- },
152
- {
153
- " name " : " Meat " ,
154
- " product " : {
155
- " name " : " steak " ,
156
- " points " : 200,
157
- " healthy " : " false " ,
158
- " delicious " : " true " ,
159
- " categories " : [ ]
160
- }
161
- },
162
- {
163
- " name " : " Cereal aisle " ,
164
- " product " : {
165
- " name " : " Sugarydoos " ,
166
- " points " : 0.5,
167
- " healthy " : " false " ,
168
- " delicious " : " maybe " ,
169
- " description " : " More sugar than you can imagine. "
170
- }
171
- }
172
- ]
173
- }
174
- """ ,
138
+ """
139
+ {
140
+ " name " : " Store " ,
141
+ " shelves " : [
142
+ {
143
+ " name " : " Discount Produce " ,
144
+ " product " : {
145
+ " name " : " Banana " ,
146
+ " points " : 200,
147
+ " description " : " A banana that's perfectly ripe. " ,
148
+ " healthy " : " true " ,
149
+ " delicious " : " true " ,
150
+ " categories " : [ " fruit " , " yellow " ]
151
+ }
152
+ },
153
+ {
154
+ " name " : " Meat " ,
155
+ " product " : {
156
+ " name " : " steak " ,
157
+ " points " : 200,
158
+ " healthy " : " false " ,
159
+ " delicious " : " true " ,
160
+ " categories " : [ ]
161
+ }
162
+ },
163
+ {
164
+ " name " : " Cereal aisle " ,
165
+ " product " : {
166
+ " name " : " Sugarydoos " ,
167
+ " points " : 0.5,
168
+ " healthy " : " false " ,
169
+ " delicious " : " maybe " ,
170
+ " description " : " More sugar than you can imagine. "
171
+ }
172
+ }
173
+ ]
174
+ }
175
+ """ ,
175
176
context: ( ) ,
176
177
provider: ConvertJSONToCodableStruct . self,
177
178
expected: [
@@ -205,23 +206,44 @@ final class SyntaxRefactorTests: XCTestCase {
205
206
}
206
207
207
208
func assertRefactor< R: EditRefactoringProvider > (
208
- malformedInput input: String ,
209
+ _ input: String ,
209
210
context: R . Context ,
210
211
provider: R . Type ,
211
212
expected: [ SourceEdit ] ,
212
213
file: StaticString = #filePath,
213
214
line: UInt = #line
214
- ) throws where R. Input == Syntax {
215
- var parser = Parser ( input)
216
- let syntax = ExprSyntax . parse ( from: & parser)
217
- try assertRefactor (
218
- Syntax ( syntax) ,
219
- context: context,
220
- provider: provider,
221
- expected: expected,
222
- file: file,
223
- line: line
224
- )
215
+ ) throws {
216
+ let ( markers, textWithoutMarkers) = extractMarkers ( input)
217
+
218
+ var parser = Parser ( textWithoutMarkers)
219
+ let sourceFile = SourceFileSyntax . parse ( from: & parser)
220
+
221
+ let markersToCheck = markers. isEmpty ? [ ( " 1️⃣ " , 0 ) ] : markers. sorted { $0. key < $1. key }
222
+
223
+ for (marker, location) in markersToCheck {
224
+ guard let token = sourceFile. token ( at: AbsolutePosition ( utf8Offset: location) ) else {
225
+ XCTFail ( " Could not find token at location \( marker) " )
226
+ continue
227
+ }
228
+
229
+ let input : R . Input
230
+ if let parentMatch = token. parent? . as ( R . Input. self) {
231
+ input = parentMatch
232
+ } else {
233
+ XCTFail ( " token at \( marker) did not match expected input: \( token) " )
234
+ continue
235
+ }
236
+
237
+ try assertRefactor (
238
+ input,
239
+ context: context,
240
+ provider: provider,
241
+ expected: expected,
242
+ at: marker,
243
+ file: file,
244
+ line: line
245
+ )
246
+ }
225
247
}
226
248
227
249
// Borrowed from the swift-syntax library's SwiftRefactor tests.
@@ -231,6 +253,7 @@ func assertRefactor<R: EditRefactoringProvider>(
231
253
context: R . Context ,
232
254
provider: R . Type ,
233
255
expected: [ SourceEdit ] ,
256
+ at marker: String ,
234
257
file: StaticString = #filePath,
235
258
line: UInt = #line
236
259
) throws {
@@ -239,7 +262,7 @@ func assertRefactor<R: EditRefactoringProvider>(
239
262
if !expected. isEmpty {
240
263
XCTFail (
241
264
"""
242
- Refactoring produced empty result, expected:
265
+ Refactoring at \( marker ) produced empty result, expected:
243
266
\( expected)
244
267
""" ,
245
268
file: file,
@@ -252,7 +275,7 @@ func assertRefactor<R: EditRefactoringProvider>(
252
275
if edits. count != expected. count {
253
276
XCTFail (
254
277
"""
255
- Refactoring produced incorrect number of edits, expected \( expected. count) not \( edits. count) .
278
+ Refactoring at \( marker ) produced incorrect number of edits, expected \( expected. count) not \( edits. count) .
256
279
257
280
Actual:
258
281
\( edits. map ( { $0. debugDescription } ) . joined ( separator: " \n " ) )
0 commit comments