@@ -134,7 +134,10 @@ class FixItApplierApplyEditsTests: XCTestCase {
134134 . init( range: 3 ..< 7 , replacement: " cd " ) ,
135135 ] ,
136136 // The second edit is skipped.
137- possibleOutputs: [ " aboo = 1 " , " varcd = 1 " ]
137+ outputs: [
138+ . init( " aboo = 1 " ) ,
139+ . init( " varcd = 1 " ) ,
140+ ]
138141 )
139142 }
140143
@@ -148,19 +151,37 @@ class FixItApplierApplyEditsTests: XCTestCase {
148151 . init( range: 0 ..< 5 , replacement: " _ " ) ,
149152 . init( range: 0 ..< 3 , replacement: " let " ) ,
150153 ] ,
151- possibleOutputs: [ " _ = 11 " , " let x = 11 " ]
154+ outputs: [
155+ . init( " _ = 11 " ) ,
156+ . init( " let x = 11 " ) ,
157+ ]
152158 )
153159 }
154160
155161 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+
156174 assertAppliedEdits (
157175 to: " x = 1 " ,
158176 edits: [
159177 . init( range: 0 ..< 0 , replacement: " var " ) ,
160178 . init( range: 0 ..< 0 , replacement: " var " ) ,
161179 . init( range: 0 ..< 0 , replacement: " var " ) ,
162180 ] ,
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+ ]
164185 )
165186 }
166187
@@ -182,28 +203,69 @@ class FixItApplierApplyEditsTests: XCTestCase {
182203 . init( range: 2 ..< 2 , replacement: " a " ) , // Insertion
183204 ] ,
184205 // 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+ ]
186210 )
187211 }
188212}
189213
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+
190224/// Asserts that at least one element in `possibleOutputs` matches the result
191225/// of applying an array of edits to `input`, for all permutations of `edits`.
192226private func assertAppliedEdits(
193227 to tree: SourceFileSyntax ,
194228 edits: [ SourceEdit ] ,
195- possibleOutputs : [ String ]
229+ outputs : [ Output ]
196230) {
197- precondition ( !possibleOutputs . isEmpty)
231+ precondition ( !outputs . isEmpty)
198232
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 {
204247 return
205248 }
206249
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+
207269 let keepGoing = indices. nextPermutation ( )
208270 guard keepGoing else {
209271 break
@@ -218,7 +280,13 @@ private func assertAppliedEdits(
218280 edits: [ SourceEdit ] ,
219281 output: String
220282) {
221- assertAppliedEdits ( to: tree, edits: edits, possibleOutputs: [ output] )
283+ assertAppliedEdits (
284+ to: tree,
285+ edits: edits,
286+ outputs: [
287+ . init( output)
288+ ]
289+ )
222290}
223291
224292// Grabbed from https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/Permutations.swift
0 commit comments