@@ -246,6 +246,186 @@ Describe "Basic FileSystem Provider Tests" -Tags "CI" {
246
246
}
247
247
}
248
248
249
+ Describe " Hard link and symbolic link tests" - Tags " CI" , " RequireAdminOnWindows" {
250
+ BeforeAll {
251
+ # on macOS, the /tmp directory is a symlink, so we'll resolve it here
252
+ $TestPath = $TestDrive
253
+ if ($IsOSX )
254
+ {
255
+ $item = Get-Item $TestPath
256
+ $dirName = $item.BaseName
257
+ $item = Get-Item $item.PSParentPath
258
+ if ($item.LinkType -eq " SymbolicLink" )
259
+ {
260
+ $TestPath = Join-Path $item.Target $dirName
261
+ }
262
+ }
263
+
264
+ $realFile = Join-Path $TestPath " file.txt"
265
+ $nonFile = Join-Path $TestPath " not-a-file"
266
+ $fileContent = " some text"
267
+ $realDir = Join-Path $TestPath " subdir"
268
+ $nonDir = Join-Path $TestPath " not-a-dir"
269
+ $hardLinkToFile = Join-Path $TestPath " hard-to-file.txt"
270
+ $symLinkToFile = Join-Path $TestPath " sym-link-to-file.txt"
271
+ $symLinkToDir = Join-Path $TestPath " sym-link-to-dir"
272
+ $symLinkToNothing = Join-Path $TestPath " sym-link-to-nowhere"
273
+ $dirSymLinkToDir = Join-Path $TestPath " symd-link-to-dir"
274
+ $junctionToDir = Join-Path $TestPath " junction-to-dir"
275
+
276
+ New-Item - ItemType File - Path $realFile - Value $fileContent > $null
277
+ New-Item - ItemType Directory - Path $realDir > $null
278
+ }
279
+
280
+ Context " New-Item and hard/symbolic links" {
281
+ It " New-Item can create a hard link to a file" {
282
+ New-Item - ItemType HardLink - Path $hardLinkToFile - Value $realFile
283
+ Test-Path $hardLinkToFile | Should Be $true
284
+ $link = Get-Item - Path $hardLinkToFile
285
+ $link.LinkType | Should BeExactly " HardLink"
286
+ Get-Content - Path $hardLinkToFile | Should be $fileContent
287
+ }
288
+ It " New-Item can create symbolic link to file" {
289
+ New-Item - ItemType SymbolicLink - Path $symLinkToFile - Value $realFile
290
+ Test-Path $symLinkToFile | Should Be $true
291
+ $real = Get-Item - Path $realFile
292
+ $link = Get-Item - Path $symLinkToFile
293
+ $link.LinkType | Should BeExactly " SymbolicLink"
294
+ $link.Target | Should Be $real.FullName
295
+ Get-Content - Path $symLinkToFile | Should be $fileContent
296
+ }
297
+ It " New-Item can create a symbolic link to nothing" {
298
+ New-Item - ItemType SymbolicLink - Path $symLinkToNothing - Value $nonFile
299
+ Test-Path $symLinkToNothing | Should Be $true
300
+ $link = Get-Item - Path $symLinkToNothing
301
+ $link.LinkType | Should BeExactly " SymbolicLink"
302
+ $link.Target | Should Be $nonFile
303
+ }
304
+ It " New-Item can create a symbolic link to a directory" - Skip:($IsWindows ) {
305
+ New-Item - ItemType SymbolicLink - Path $symLinkToDir - Value $realDir
306
+ Test-Path $symLinkToDir | Should Be $true
307
+ $real = Get-Item - Path $realDir
308
+ $link = Get-Item - Path $symLinkToDir
309
+ $link.LinkType | Should BeExactly " SymbolicLink"
310
+ $link.Target | Should Be $real.FullName
311
+ }
312
+ It " New-Item can create a directory symbolic link to a directory" - Skip:(-Not $IsW
10000
indows ) {
313
+ New-Item - ItemType SymbolicLink - Path $symLinkToDir - Value $realDir
314
+ Test-Path $symLinkToDir | Should Be $true
315
+ $real = Get-Item - Path $realDir
316
+ $link = Get-Item - Path $symLinkToDir
317
+ $link | Should BeOfType System.IO.DirectoryInfo
318
+ $link.LinkType | Should BeExactly " SymbolicLink"
319
+ $link.Target | Should Be $real.FullName
320
+ }
321
+ It " New-Item can create a directory junction to a directory" - Skip:(-Not $IsWindows ) {
322
+ New-Item - ItemType Junction - Path $junctionToDir - Value $realDir
323
+ Test-Path $junctionToDir | Should Be $true
324
+ }
325
+ }
326
+
327
+ Context " Remove-Item and hard/symbolic links" {
328
+ BeforeAll {
329
+ $testCases = @ (
330
+ @ {
331
+ Name = " Remove-Item can remove a hard link to a file"
332
+ Link = $hardLinkToFile
333
+ Target = $realFile
334
+ }
335
+ @ {
336
+ Name = " Remove-Item can remove a symbolic link to a file"
337
+ Link = $symLinkToFile
338
+ Target = $realFile
339
+ }
340
+ )
341
+
342
+ # New-Item on Windows will not create a "plain" symlink to a directory
343
+ $unixTestCases = @ (
344
+ @ {
345
+ Name = " Remove-Item can remove a symbolic link to a directory on Unix"
346
+ Link = $symLinkToDir
347
+ Target = $realDir
348
+ }
349
+ )
350
+
351
+ # Junctions and directory symbolic links are Windows and NTFS only
352
+ $windowsTestCases = @ (
353
+ @ {
354
+ Name = " Remove-Item can remove a symbolic link to a directory on Windows"
355
+ Link = $symLinkToDir
356
+ Target = $realDir
357
+ }
358
+ @ {
359
+ Name = " Remove-Item can remove a directory symbolic link to a directory on Windows"
360
+ Link = $dirSymLinkToDir
361
+ Target = $realDir
362
+ }
363
+ @ {
364
+ Name = " Remove-Item can remove a junction to a directory"
365
+ Link = $junctionToDir
366
+ Target = $realDir
367
+ }
368
+ )
369
+
370
+ function TestRemoveItem
371
+ {
372
+ Param (
373
+ [string ]$Link ,
374
+ [string ]$Target
375
+ )
376
+
377
+ Remove-Item - Path $Link - ErrorAction SilentlyContinue > $null
378
+ Test-Path - Path $Link | Should Be $false
379
+ Test-Path - Path $Target | Should Be $true
380
+ }
381
+ }
382
+
383
+ It " <Name>" - TestCases $testCases {
384
+ Param (
385
+ [string ]$Name ,
386
+ [string ]$Link ,
387
+ [string ]$Target
388
+ )
389
+
390
+ TestRemoveItem $Link $Target
391
+ }
392
+
393
+ It " <Name>" - TestCases $unixTestCases - Skip:($IsWindows ) {
394
+ Param (
395
+ [string ]$Name ,
396
+ [string ]$Link ,
397
+ [string ]$Target
398
+ )
399
+
400
+ TestRemoveItem $Link $Target
401
+ }
402
+
403
+ It " <Name>" - TestCases $windowsTestCases - Skip:(-not $IsWindows ) {
404
+ Param (
405
+ [string ]$Name ,
406
+ [string ]$Link ,
407
+ [string ]$Target
408
+ )
409
+
410
+ TestRemoveItem $Link $Target
411
+ }
412
+
413
+ It " Remove-Item ignores -Recurse switch when deleting symlink to directory" {
414
+ $folder = Join-Path $TestDrive " folder"
415
+ $file = Join-Path $TestDrive " folder" " file"
416
+ $link = Join-Path $TestDrive " sym-to-folder"
417
+ New-Item - ItemType Directory - Path $folder > $null
418
+ New-Item - ItemType File - Path $file - Value " some content" > $null
419
+ New-Item - ItemType SymbolicLink - Path $link - value $folder > $null
420
+ $childA = Get-Childitem $folder
421
+ Remove-Item - Path $link - Recurse
422
+ $childB = Get-ChildItem $folder
423
+ $childB.Count | Should Be 1
424
+ $childB.Count | Should BeExactly $childA.Count
425
+ $childB.Name | Should BeExactly $childA.Name
426
+ }
427
+ }
428
+ }
249
429
250
430
Describe " Copy-Item can avoid copying an item onto itself" - Tags " CI" , " RequireAdminOnWindows" {
251
431
BeforeAll {
0 commit comments