11import { expect } from "chai"
22import * as path from "path"
3+ import * as os from "os"
4+ import * as fs from "fs"
35import * as sinon from "sinon"
46import ApplyEditAdapter from "../../lib/adapters/apply-edit-adapter"
57import Convert from "../../lib/convert"
@@ -9,6 +11,7 @@ const TEST_PATH1 = normalizeDriveLetterName(path.join(__dirname, "test.txt"))
911const TEST_PATH2 = normalizeDriveLetterName ( path . join ( __dirname , "test2.txt" ) )
1012const TEST_PATH3 = normalizeDriveLetterName ( path . join ( __dirname , "test3.txt" ) )
1113const TEST_PATH4 = normalizeDriveLetterName ( path . join ( __dirname , "test4.txt" ) )
14+ const tempDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'atom-languageclient-tests' ) )
1215
1316function normalizeDriveLetterName ( filePath : string ) : string {
1417 if ( process . platform === "win32" ) {
@@ -186,5 +189,235 @@ describe("ApplyEditAdapter", () => {
186189 expect ( errorCalls . length ) . to . equal ( 1 )
187190 expect ( errorCalls [ 0 ] . args [ 1 ] . detail ) . to . equal ( `Out of range edit on ${ TEST_PATH4 } :1:2` )
188191 } )
192+
193+ it ( "handles rename resource operations" , async ( ) => {
194+ const directory = fs . mkdtempSync ( tempDir )
195+ const oldUri = path . join ( directory , "test.txt" )
196+ const newUri = path . join ( directory , "test-renamed.txt" )
197+ fs . writeFileSync ( oldUri , 'abcd' )
198+
199+ const result = await ApplyEditAdapter . onApplyEdit ( {
200+ edit : {
201+ documentChanges : [
202+ {
203+ kind : "rename" ,
204+ oldUri : oldUri ,
205+ newUri : newUri ,
206+ }
207+ ]
208+ } ,
209+ } )
210+
211+ expect ( result . applied ) . to . equal ( true )
212+ expect ( fs . existsSync ( newUri ) ) . to . equal ( true )
213+ expect ( fs . readFileSync ( newUri ) . toString ( ) ) . to . equal ( 'abcd' )
214+ expect ( fs . existsSync ( oldUri ) ) . to . equal ( false )
215+ } )
216+
217+ it ( "handles rename operation with ignoreIfExists option" , async ( ) => {
218+ const directory = fs . mkdtempSync ( tempDir )
219+ const oldUri = path . join ( directory , "test.txt" )
220+ const newUri = path . join ( directory , "test-renamed.txt" )
221+ fs . writeFileSync ( oldUri , 'abcd' )
222+ fs . writeFileSync ( newUri , 'efgh' )
223+
224+ const result = await ApplyEditAdapter . onApplyEdit ( {
225+ edit : {
226+ documentChanges : [
227+ {
228+ kind : "rename" ,
229+ oldUri : oldUri ,
230+ newUri : newUri ,
231+ options : {
232+ ignoreIfExists : true
233+ }
234+ }
235+ ]
236+ } ,
237+ } )
238+
239+ expect ( result . applied ) . to . equal ( true )
240+ expect ( fs . existsSync ( oldUri ) ) . to . equal ( true )
241+ expect ( fs . readFileSync ( newUri ) . toString ( ) ) . to . equal ( 'efgh' )
242+ } )
243+
244+ it ( "handles rename operation with overwrite option" , async ( ) => {
245+ const directory = fs . mkdtempSync ( tempDir )
246+ const oldUri = path . join ( directory , "test.txt" )
247+ const newUri = path . join ( directory , "test-renamed.txt" )
248+ fs . writeFileSync ( oldUri , 'abcd' )
249+ fs . writeFileSync ( newUri , 'efgh' )
250+
251+ const result = await ApplyEditAdapter . onApplyEdit ( {
252+ edit : {
253+ documentChanges : [
254+ {
255+ kind : "rename" ,
256+ oldUri : oldUri ,
257+ newUri : newUri ,
258+ options : {
259+ overwrite : true ,
260+ ignoreIfExists : true // Overwrite wins over ignoreIfExists
261+ }
262+ }
263+ ]
264+ } ,
265+ } )
266+
267+ expect ( result . applied ) . to . equal ( true )
268+ expect ( fs . existsSync ( oldUri ) ) . to . equal ( false )
269+ expect ( fs . readFileSync ( newUri ) . toString ( ) ) . to . equal ( 'abcd' )
270+ } )
271+
272+ it ( "throws an error on rename operation if target exists" , async ( ) => {
273+ const directory = fs . mkdtempSync ( tempDir )
274+ const oldUri = path . join ( directory , "test.txt" )
275+ const newUri = path . join ( directory , "test-renamed.txt" )
276+ fs . writeFileSync ( oldUri , 'abcd' )
277+ fs . writeFileSync ( newUri , 'efgh' )
278+
279+ const result = await ApplyEditAdapter . onApplyEdit ( {
280+ edit : {
281+ documentChanges : [
282+ {
283+ kind : "rename" ,
284+ oldUri : oldUri ,
285+ newUri : newUri ,
286+ }
287+ ]
288+ } ,
289+ } )
290+
291+ expect ( result . applied ) . to . equal ( false )
292+ expect ( fs . existsSync ( oldUri ) ) . to . equal ( true )
293+ expect ( fs . readFileSync ( oldUri ) . toString ( ) ) . to . equal ( 'abcd' )
294+ expect ( fs . existsSync ( newUri ) ) . to . equal ( true )
295+ expect ( fs . readFileSync ( newUri ) . toString ( ) ) . to . equal ( 'efgh' )
296+
297+ expect (
298+ ( atom as any ) . notifications . addError . calledWith ( "workspace/applyEdits failed" , {
299+ description : "Failed to apply edits." ,
300+ detail : "Error during rename resource operation: Target exists." ,
301+ } )
302+ ) . to . equal ( true )
303+ } )
304+
305+ it ( "handles delete resource operations on files" , async ( ) => {
306+ const directory = fs . mkdtempSync ( tempDir )
307+ const uri = path . join ( directory , "test.txt" )
308+ fs . writeFileSync ( uri , 'abcd' )
309+
310+ const result = await ApplyEditAdapter . onApplyEdit ( {
311+ edit : {
312+ documentChanges : [
313+ {
314+ kind : "delete" ,
315+ uri : uri
316+ }
317+ ]
318+ } ,
319+ } )
320+
321+ expect ( result . applied ) . to . equal ( true )
322+ expect ( fs . existsSync ( uri ) ) . to . equal ( false )
323+ } )
324+
325+ it ( "handles delete resource operations on directories" , async ( ) => {
326+ const directory = fs . mkdtempSync ( tempDir )
327+ const file1 = path . join ( directory , '1.txt' )
328+ const file2 = path . join ( directory , '2.txt' )
329+ fs . writeFileSync ( file1 , '1' )
330+ fs . writeFileSync ( file2 , '2' )
331+
332+ const result = await ApplyEditAdapter . onApplyEdit ( {
333+ edit : {
334+ documentChanges : [
335+ {
336+ kind : "delete" ,
337+ uri : directory ,
338+ options : {
339+ recursive : true
340+ }
341+ }
342+ ]
343+ } ,
344+ } )
345+
346+ expect ( result . applied ) . to . equal ( true )
347+ expect ( fs . existsSync ( directory ) ) . to . equal ( false )
348+ expect ( fs . existsSync ( file1 ) ) . to . equal ( false )
349+ expect ( fs . existsSync ( file2 ) ) . to . equal ( false )
350+ } )
351+
352+ it ( "throws an error when deleting a non-empty directory without recursive option" , async ( ) => {
353+ const directory = fs . mkdtempSync ( tempDir )
354+ const file1 = path . join ( directory , '1.txt' )
355+ const file2 = path . join ( directory , '2.txt' )
356+ fs . writeFileSync ( file1 , '1' )
357+ fs . writeFileSync ( file2 , '2' )
358+
359+ const result = await ApplyEditAdapter . onApplyEdit ( {
360+ edit : {
361+ documentChanges : [
362+ {
363+ kind : "delete" ,
364+ uri : directory ,
365+ options : {
366+ recursive : false
367+ }
368+ }
369+ ]
370+ } ,
371+ } )
372+
373+ expect ( result . applied ) . to . equal ( false )
374+ expect ( fs . existsSync ( directory ) ) . to . equal ( true )
375+ expect ( fs . existsSync ( file1 ) ) . to . equal ( true )
376+ expect ( fs . existsSync ( file2 ) ) . to . equal ( true )
377+ const errorCalls = ( atom as any ) . notifications . addError . getCalls ( )
378+ expect ( errorCalls . length ) . to . equal ( 1 )
379+ expect ( errorCalls [ 0 ] . args [ 1 ] . detail ) . to . match ( / E r r o r d u r i n g d e l e t e r e s o u r c e o p e r a t i o n : ( .* ) / )
380+ } )
381+
382+
383+ it ( "throws an error on delete operation if target doesnt exist" , async ( ) => {
384+ const result = await ApplyEditAdapter . onApplyEdit ( {
385+ edit : {
386+ documentChanges : [
387+ {
388+ kind : "delete" ,
389+ uri : path . join ( tempDir , "unexisting.txt" ) ,
390+ }
391+ ]
392+ } ,
393+ } )
394+ //
395+ expect ( result . applied ) . to . equal ( false )
396+ expect (
397+ ( atom as any ) . notifications . addError . calledWith ( "workspace/applyEdits failed" , {
398+ description : "Failed to apply edits." ,
399+ detail : "Error during delete resource operation: Target doesn't exist." ,
400+ } )
401+ ) . to . equal ( true )
402+ } )
403+
404+ it ( "handles create resource operations" , async ( ) => {
405+ const directory = fs . mkdtempSync ( tempDir )
406+ const uri = path . join ( directory , "test.txt" )
407+
408+ const result = await ApplyEditAdapter . onApplyEdit ( {
409+ edit : {
410+ documentChanges : [
411+ {
412+ kind : "create" ,
413+ uri : uri
414+ }
415+ ]
416+ } ,
417+ } )
418+
419+ expect ( result . applied ) . to . equal ( true )
420+ expect ( fs . existsSync ( uri ) ) . to . equal ( true )
421+ } )
189422 } )
190423} )
0 commit comments