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