@@ -138,7 +138,10 @@ class FixItApplierApplyEditsTests: XCTestCase {
138
138
. init( range: 3 ..< 7 , replacement: " cd " ) ,
139
139
] ,
140
140
// The second edit is skipped.
141
- possibleOutputs: [ " aboo = 1 " , " varcd = 1 " ]
141
+ outputs: [
142
+ . init( " aboo = 1 " ) ,
143
+ . init( " varcd = 1 " ) ,
144
+ ]
142
145
)
143
146
}
144
147
@@ -152,19 +155,37 @@ class FixItApplierApplyEditsTests: XCTestCase {
152
155
. init( range: 0 ..< 5 , replacement: " _ " ) ,
153
156
. init( range: 0 ..< 3 , replacement: " let " ) ,
154
157
] ,
155
- possibleOutputs: [ " _ = 11 " , " let x = 11 " ]
158
+ outputs: [
159
+ . init( " _ = 11 " ) ,
160
+ . init( " let x = 11 " ) ,
161
+ ]
156
162
)
157
163
}
158
164
159
165
func testMultipleOverlappingInsertions( ) {
166
+ assertAppliedEdits (
167
+ to: " x = 1 " ,
168
+ edits: [
169
+ . init( range: 1 ..< 1 , replacement: " y " ) ,
170
+ . init( range: 1 ..< 1 , replacement: " z " ) ,
171
+ ] ,
172
+ outputs: [
173
+ . init( " xyz = 1 " ) ,
174
+ . init( " xzy = 1 " ) ,
175
+ ]
176
+ )
177
+
160
178
assertAppliedEdits (
161
179
to: " x = 1 " ,
162
180
edits: [
163
181
. init( range: 0 ..< 0 , replacement: " var " ) ,
164
182
. init( range: 0 ..< 0 , replacement: " var " ) ,
165
183
. init( range: 0 ..< 0 , replacement: " var " ) ,
166
184
] ,
167
- output: " var var var x = 1 "
185
+ outputs: [
186
+ . init( " var var var x = 1 " , allowDuplicateInsertions: true ) ,
187
+ . init( " var x = 1 " , allowDuplicateInsertions: false ) ,
188
+ ]
168
189
)
169
190
}
170
191
@@ -186,28 +207,69 @@ class FixItApplierApplyEditsTests: XCTestCase {
186
207
. init( range: 2 ..< 2 , replacement: " a " ) , // Insertion
187
208
] ,
188
209
// FIXME: This behavior where these edits are not considered overlapping doesn't feel desirable
189
- possibleOutputs: [ " _x = 1 " , " _ a= 1 " ]
210
+ outputs: [
211
+ . init( " _x = 1 " ) ,
212
+ . init( " _ a= 1 " ) ,
213
+ ]
190
214
)
191
215
}
192
216
}
193
217
218
+ private struct Output {
219
+ var result : String
220
+ var allowDuplicateInsertions : Bool ?
221
+
222
+ init ( _ result: String , allowDuplicateInsertions: Bool ? = nil ) {
223
+ self . result = result
224
+ self . allowDuplicateInsertions = allowDuplicateInsertions
225
+ }
226
+ }
227
+
194
228
/// Asserts that at least one element in `possibleOutputs` matches the result
195
229
/// of applying an array of edits to `input`, for all permutations of `edits`.
196
230
private func assertAppliedEdits(
197
231
to tree: SourceFileSyntax ,
198
232
edits: [ SourceEdit ] ,
199
- possibleOutputs : [ String ]
233
+ outputs : [ Output ]
200
234
) {
201
- precondition ( !possibleOutputs . isEmpty)
235
+ precondition ( !outputs . isEmpty)
202
236
203
- var indices = Array ( edits. indices)
204
- while true {
205
- let result = FixItApplier . apply ( edits: indices. map { edits [ $0] } , to: tree)
206
- guard possibleOutputs. contains ( result) else {
207
- XCTFail ( " \" \( result) \" is not equal to either of \( possibleOutputs) " )
237
+ func assertAppliedEdits(
238
+ permutation: [ SourceEdit ] ,
239
+ allowDuplicateInsertions: Bool
240
+ ) {
241
+ // Filter out the results that match this setting.
242
+ let viableResults : [ String ] = outputs. compactMap { output in
243
+ if output. allowDuplicateInsertions == !allowDuplicateInsertions {
244
+ return nil
245
+ }
246
+
247
+ return output. result
248
+ }
249
+
250
+ guard !viableResults. isEmpty else {
208
251
return
209
252
}
210
253
254
+ let result = FixItApplier . apply (
255
+ edits: permutation,
256
+ to: tree,
257
+ allowDuplicateInsertions: allowDuplicateInsertions
258
+ )
259
+
260
+ guard viableResults. contains ( result) else {
261
+ XCTFail ( " \" \( result) \" is not equal to either of \( viableResults) " )
262
+ return
263
+ }
264
+ }
265
+
266
+ var indices = Array ( edits. indices)
267
+ while true {
268
+ let permutation = indices. map { edits [ $0] }
269
+
270
+ assertAppliedEdits ( permutation: permutation, allowDuplicateInsertions: true )
271
+ assertAppliedEdits ( permutation: permutation, allowDuplicateInsertions: false )
272
+
211
273
let keepGoing = indices. nextPermutation ( )
212
274
guard keepGoing else {
213
275
break
@@ -222,7 +284,13 @@ private func assertAppliedEdits(
222
284
edits: [ SourceEdit ] ,
223
285
output: String
224
286
) {
225
- assertAppliedEdits ( to: tree, edits: edits, possibleOutputs: [ output] )
287
+ assertAppliedEdits (
288
+ to: tree,
289
+ edits: edits,
290
+ outputs: [
291
+ . init( output)
292
+ ]
293
+ )
226
294
}
227
295
228
296
// Grabbed from https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/Permutations.swift
0 commit comments