Public/New-ItemLink.Tests.ps1
$here = Split-Path -Parent $MyInvocation.MyCommand.Path $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.' . "$here\$sut" Describe "New-ItemLink" -Tag 'Unit' { $testDrive = Convert-Path 'TestDrive:\' # Note: All our test files will be hidden files, for the sake of Windows # Source of truth $testFileFullName = Join-Path $testDrive '.testfile' $testDirectoryFullName = Join-Path $testDrive '.testdirectory' # Link $testFileLinkFullName = Join-Path $testDrive '.testfilelink' $testDirectoryLinkFullName = Join-Path $testDrive '.testdirectorylink' AfterEach { # Powershell 5 requires a special way to remove a SymbolicLink, see: https://stackoverflow.com/a/63172492 if ($PSVersionTable.PSVersion.Major -le 5) { Get-ChildItem "$testDrive/*" -Attributes ReparsePoint | % { $_.Delete() } } Get-Item "$testDrive/*" -Force | Remove-Item -Recurse -Force } Context 'Exceptions' { It "Should throw when ItemType is invalid" { $testFile = New-Item $testFileFullName -ItemType File -Force $testFile.Attributes += 'Hidden' $params = @{ ItemType = 'foo' Path = $testFileLinkFullName Value = $testFile.FullName ErrorAction = 'Stop' } { New-ItemLink @params } | Should -Throw 'does not belong to the set' } } Context 'Error stream' { It "Should output to error stream" { $testFile = New-Item $testFileFullName -ItemType File -Force $testFile.Attributes += 'Hidden' $params = @{ ItemType = 'SymbolicLink' Path = $testFile.FullName # Deliberately simulate an error by trying to create a link in place of its file Value = $testFile.FullName ErrorVariable = 'err' ErrorAction = 'Continue' } $err = New-ItemLink @params 2>&1 $err | ? { $_ -is [System.Management.Automation.ErrorRecord] } | Should -Not -Be $null } It "Should not output to error stream" { $testFile = New-Item $testFileFullName -ItemType File -Force $testFile.Attributes += 'Hidden' $params = @{ ItemType = 'SymbolicLink' Path = $testFile.FullName # Deliberately simulate an error by trying to create a link in place of its file Value = $testFile.FullName ErrorAction = 'SilentlyContinue' } $err = New-ItemLink @params 2>&1 $err | ? { $_ -is [System.Management.Automation.ErrorRecord] } | Should -Be $null } } Context 'Behavior' { It "Should create HardLink for file" { $testFile = New-Item $testFileFullName -ItemType File -Force $testFile.Attributes += 'Hidden' $params = @{ ItemType = 'HardLink' Path = $testFileLinkFullName Value = $testFile.FullName ErrorAction = 'Stop' } $result = New-ItemLink @params $result | Should -BeOfType [System.IO.FileInfo] $result.LinkType | Should -Be $params['ItemType'] } It 'Should create a HardLink for file even if it already exists when using -Force' { $testFile = New-Item $testFileFullName -ItemType File -Force $testFile.Attributes += 'Hidden' $testFileLink = New-Item $testFileLinkFullName -Value $testFile.FullName -ItemType 'HardLink' -Force $testFileLink.Attributes += 'Hidden' $params = @{ ItemType = 'HardLink' Path = $testFileLink.FullName Value = $testFile.FullName Force = $true ErrorAction = 'Stop' } $result = New-ItemLink @params $result | Should -BeOfType [System.IO.FileInfo] $result.LinkType | Should -Be $params['ItemType'] } It "Should create SymbolicLink for file" { $testFile = New-Item $testFileFullName -ItemType File -Force $testFile.Attributes += 'Hidden' $params = @{ ItemType = 'SymbolicLink' Path = $testFileLinkFullName Value = $testFile.FullName ErrorAction = 'Stop' } $result = New-ItemLink @params $result | Should -BeOfType [System.IO.FileInfo] $result.LinkType | Should -Be $params['ItemType'] } It "Should create Junction for directory (Windows)" { if ($env:OS -eq 'Windows_NT') { $testDirectory = New-Item $testDirectoryFullName -ItemType Directory -Force $testDirectory.Attributes += 'Hidden' $params = @{ ItemType = 'Junction' Path = $testDirectoryLinkFullName Value = $testDirectory.FullName ErrorAction = 'Stop' } $result = New-ItemLink @params $result | Should -BeOfType [System.IO.DirectoryInfo] $result.LinkType | Should -Be $params['ItemType'] }else { $true } } It 'Should create a Junction for directory even if it already exists when using -Force (Windows)' { if ($env:OS -eq 'Windows_NT') { $testDirectory = New-Item $testDirectoryFullName -ItemType Directory -Force $testDirectory.Attributes += 'Hidden' $testDirectoryLink = New-Item $testDirectoryLinkFullName -Value $testDirectory.FullName -ItemType 'Junction' -Force $testDirectoryLink.Attributes += 'Hidden' $params = @{ ItemType = 'Junction' Path = $testDirectoryLink.FullName Value = $testDirectory.FullName Force = $true ErrorAction = 'Stop' } $result = New-ItemLink @params $result | Should -BeOfType [System.IO.DirectoryInfo] $result.LinkType | Should -Be $params['ItemType'] }else { $true } } It "Should create SymbolicLink for directory" { $testDirectory = New-Item $testDirectoryFullName -ItemType Directory -Force $testDirectory.Attributes += 'Hidden' $params = @{ ItemType = 'SymbolicLink' Path = $testDirectoryLinkFullName Value = $testDirectory.FullName ErrorAction = 'Stop' } $result = New-ItemLink @params $result | Should -BeOfType [System.IO.DirectoryInfo] $result.LinkType | Should -Be $params['ItemType'] } It 'Should create a SymbolicLink for directory even if it already exists when using -Force' { $testDirectory = New-Item $testDirectoryFullName -ItemType Directory -Force $testDirectory.Attributes += 'Hidden' $testDirectoryLink = New-Item $testDirectoryLinkFullName -Value $testDirectory.FullName -ItemType 'SymbolicLink' -Force $testDirectoryLink.Attributes += 'Hidden' $params = @{ ItemType = 'SymbolicLink' Path = $testDirectoryLink.FullName Value = $testDirectory.FullName Force = $true ErrorAction = 'Stop' } $result = New-ItemLink @params $result | Should -BeOfType [System.IO.DirectoryInfo] $result.LinkType | Should -Be $params['ItemType'] } } } |