From 7305b82b73df5af7eb9b50fbdfc8ce7e29615cd9 Mon Sep 17 00:00:00 2001 From: PowerShell Team Date: Wed, 20 Jul 2016 14:28:19 -0700 Subject: [PATCH] Add migrated files --- .../Pester.Commands.Cmdlets.ArchiveTests.ps1 | 951 +++++++++++ .../SamplePreCreatedArchive.archive | Bin 0 -> 270 bytes .../History.Tests.ps1 | 64 + .../Pester.Commands.Cmdlets.GetCommand.ps1 | 49 + .../core.job.tests.ps1 | 42 + .../Copy.Item.Tests.ps1 | 867 ++++++++++ ...mands.Cmdlets.NoNewlineParameter.Tests.ps1 | 26 + .../FormatHex.Tests.ps1 | 218 +++ .../ImportExportCSV.Delimiter.Tests.ps1 | 65 + .../MiscCmdletUpdates.Tests.ps1 | 54 + .../NewGuid.Tests.ps1 | 19 + .../NewTemporaryFile.Tests.ps1 | 38 + .../Pester.Commands.Cmdlets.JsonTests.ps1 | 1465 +++++++++++++++++ .../PowerShellData.tests.ps1 | 86 + .../alias.tests.ps1 | 160 ++ .../clixml.tests.ps1 | 187 +++ .../command.tests.ps1 | 80 + .../formatdata.tests.ps1 | 64 + .../object.tests.ps1 | 100 ++ .../string.tests.ps1 | 61 + .../typedata.tests.ps1 | Bin 0 -> 10702 bytes .../xml.tests.ps1 | 62 + 22 files changed, 4658 insertions(+) create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Archive/Pester.Commands.Cmdlets.ArchiveTests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Archive/SamplePreCreatedArchive.archive create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Core/History.Tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Core/Pester.Commands.Cmdlets.GetCommand.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Core/core.job.tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Management/Copy.Item.Tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Management/Pester.Commands.Cmdlets.NoNewlineParameter.Tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/FormatHex.Tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/ImportExportCSV.Delimiter.Tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/MiscCmdletUpdates.Tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/NewGuid.Tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/NewTemporaryFile.Tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/Pester.Commands.Cmdlets.JsonTests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/alias.tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/clixml.tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/command.tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/formatdata.tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/object.tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/string.tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/typedata.tests.ps1 create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/xml.tests.ps1 diff --git a/test/powershell/Modules/Microsoft.PowerShell.Archive/Pester.Commands.Cmdlets.ArchiveTests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Archive/Pester.Commands.Cmdlets.ArchiveTests.ps1 new file mode 100644 index 0000000000..387b0eb32e --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Archive/Pester.Commands.Cmdlets.ArchiveTests.ps1 @@ -0,0 +1,951 @@ +<############################################################################################ + # File: Pester.Commands.Cmdlets.ArchiveTests.ps1 + # Commands.Cmdlets.ArchiveTests suite contains Tests that are + # used for validating Microsoft.PowerShell.Archive module. + ############################################################################################> +$script:TestSourceRoot = $PSScriptRoot +Describe "Test suite for Microsoft.PowerShell.Archive module" -Tags "BVT" { + + BeforeAll { + + New-Item $TestDrive\SourceDir -Type Directory | Out-Null + New-Item $TestDrive\SourceDir\ChildDir-1 -Type Directory | Out-Null + New-Item $TestDrive\SourceDir\ChildDir-2 -Type Directory | Out-Null + New-Item $TestDrive\SourceDir\ChildEmptyDir -Type Directory | Out-Null + + $content = "Some Data" + $content | Out-File -FilePath $TestDrive\SourceDir\Sample-1.txt + $content | Out-File -FilePath $TestDrive\SourceDir\Sample-2.txt + $content | Out-File -FilePath $TestDrive\SourceDir\ChildDir-1\Sample-3.txt + $content | Out-File -FilePath $TestDrive\SourceDir\ChildDir-1\Sample-4.txt + $content | Out-File -FilePath $TestDrive\SourceDir\ChildDir-2\Sample-5.txt + $content | Out-File -FilePath $TestDrive\SourceDir\ChildDir-2\Sample-6.txt + + "Some Text" > $TestDrive\Sample.unzip + "Some Text" > $TestDrive\Sample.cab + + $preCreatedArchivePath = Join-Path $script:TestSourceRoot "SamplePreCreatedArchive.archive" + Copy-Item $preCreatedArchivePath $TestDrive\SamplePreCreatedArchive.zip -Force + } + + function Add-CompressionAssemblies { + Add-Type -AssemblyName System.IO.Compression + if ($psedition -eq "Core") + { + Add-Type -AssemblyName System.IO.Compression.ZipFile + } + else + { + Add-Type -AssemblyName System.IO.Compression.FileSystem + } + } + + function CompressArchivePathParameterSetValidator { + param + ( + [string[]] $path, + [string] $destinationPath, + [string] $compressionLevel = "Optimal" + ) + + try + { + Compress-Archive -Path $path -DestinationPath $destinationPath -CompressionLevel $compressionLevel + trow "ValidateNotNullOrEmpty attribute is missing on one of parameters belonging to Path parameterset." + } + catch + { + $_.FullyQualifiedErrorId | Should Be "ParameterArgumentValidationError,Compress-Archive" + } + } + + function CompressArchiveLiteralPathParameterSetValidator { + param + ( + [string[]] $literalPath, + [string] $destinationPath, + [string] $compressionLevel = "Optimal" + ) + + try + { + Compress-Archive -LiteralPath $literalPath -DestinationPath $destinationPath -CompressionLevel $compressionLevel + throw "ValidateNotNullOrEmpty attribute is missing on one of parameters belonging to LiteralPath parameterset." + } + catch + { + $_.FullyQualifiedErrorId | Should Be "ParameterArgumentValidationError,Compress-Archive" + } + } + + + function CompressArchiveInValidPathValidator { + param + ( + [string[]] $path, + [string] $destinationPath, + [string] $invalidPath, + [string] $expectedFullyQualifiedErrorId + ) + + try + { + Compress-Archive -Path $path -DestinationPath $destinationPath + throw "Failed to validate that an invalid Path $invalidPath was supplied as input to Compress-Archive cmdlet." + } + catch + { + $_.FullyQualifiedErrorId | Should Be $expectedFullyQualifiedErrorId + } + } + + function CompressArchiveInValidArchiveFileExtensionValidator { + param + ( + [string[]] $path, + [string] $destinationPath, + [string] $invalidArchiveFileExtension + ) + + try + { + Compress-Archive -Path $path -DestinationPath $destinationPath + throw "Failed to validate that an invalid archive file format $invalidArchiveFileExtension was supplied as input to Compress-Archive cmdlet." + } + catch + { + $_.FullyQualifiedErrorId | Should Be "NotSupportedArchiveFileExtension,Compress-Archive" + } + } + + function Validate-ArchiveEntryCount { + param + ( + [string] $path, + [int] $expectedEntryCount + ) + + Add-CompressionAssemblies + try + { + $archiveFileStreamArgs = @($path, [System.IO.FileMode]::Open) + $archiveFileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $archiveFileStreamArgs + + $zipArchiveArgs = @($archiveFileStream, [System.IO.Compression.ZipArchiveMode]::Read, $false) + $zipArchive = New-Object -TypeName System.IO.Compression.ZipArchive -ArgumentList $zipArchiveArgs + + $actualEntryCount = $zipArchive.Entries.Count + $actualEntryCount | Should Be $expectedEntryCount + } + finally + { + if ($null -ne $zipArchive) { $zipArchive.Dispose()} + if ($null -ne $archiveFileStream) { $archiveFileStream.Dispose() } + } + } + + function ArchiveFileEntryContentValidator { + param + ( + [string] $path, + [string] $entryFileName, + [string] $expectedEntryFileContent + ) + + Add-CompressionAssemblies + try + { + $destFile = "$TestDrive\ExpandedFile"+([System.Guid]::NewGuid().ToString())+".txt" + + $archiveFileStreamArgs = @($path, [System.IO.FileMode]::Open) + $archiveFileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $archiveFileStreamArgs + + $zipArchiveArgs = @($archiveFileStream, [System.IO.Compression.ZipArchiveMode]::Read, $false) + $zipArchive = New-Object -TypeName System.IO.Compression.ZipArchive -ArgumentList $zipArchiveArgs + + $entryToBeUpdated = $zipArchive.Entries | ? {$_.FullName -eq $entryFileName} + + if($entryToBeUpdated -ne $null) + { + $srcStream = $entryToBeUpdated.Open() + $destStream = New-Object "System.IO.FileStream" -ArgumentList( $destFile, [System.IO.FileMode]::Create ) + $srcStream.CopyTo( $destStream ) + $destStream.Dispose() + $srcStream.Dispose() + Get-Content $destFile | Should Be $expectedEntryFileContent + } + else + { + throw "Failed to find the file $entryFileName in the archive file $path" + } + } + finally + { + if ($zipArchive) + { + $zipArchive.Dispose() + } + if ($archiveFileStream) + { + $archiveFileStream.Dispose() + } + } + } + + function ExpandArchiveInvalidParameterValidator { + param + ( + [boolean] $isLiteralPathParameterSet, + [string[]] $path, + [string] $destinationPath, + [string] $expectedFullyQualifiedErrorId + ) + + try + { + if($isLiteralPathParameterSet) + { + Expand-Archive -LiteralPath $literalPath -DestinationPath $destinationPath + } + else + { + Expand-Archive -Path $path -DestinationPath $destinationPath + } + + throw "Expand-Archive did NOT throw expected error" + } + catch + { + $_.FullyQualifiedErrorId | Should Be $expectedFullyQualifiedErrorId + } + } + + Context "Compress-Archive - Parameter validation test cases" { + + It "Validate errors from Compress-Archive with NULL & EMPTY values for Path, LiteralPath, DestinationPath, CompressionLevel parameters" { + $sourcePath = "$TestDrive\SourceDir" + $destinationPath = "$TestDrive\SampleSingleFile.zip" + + CompressArchivePathParameterSetValidator $null $destinationPath + CompressArchivePathParameterSetValidator $sourcePath $null + CompressArchivePathParameterSetValidator $null $null + + CompressArchivePathParameterSetValidator "" $destinationPath + CompressArchivePathParameterSetValidator $sourcePath "" + CompressArchivePathParameterSetValidator "" "" + + CompressArchivePathParameterSetValidator $null $null "NoCompression" + + CompressArchiveLiteralPathParameterSetValidator $null $destinationPath + CompressArchiveLiteralPathParameterSetValidator $sourcePath $null + CompressArchiveLiteralPathParameterSetValidator $null $null + + CompressArchiveLiteralPathParameterSetValidator "" $destinationPath + CompressArchiveLiteralPathParameterSetValidator $sourcePath "" + CompressArchiveLiteralPathParameterSetValidator "" "" + + CompressArchiveLiteralPathParameterSetValidator $null $null "NoCompression" + + CompressArchiveLiteralPathParameterSetValidator $sourcePath $destinationPath $null + CompressArchiveLiteralPathParameterSetValidator $sourcePath $destinationPath "" + } + + It "Validate errors from Compress-Archive when invalid path (non-existing path / non-filesystem path) is supplied for Path or LiteralPath parameters" { + CompressArchiveInValidPathValidator "$TestDrive\InvalidPath" $TestDrive "$TestDrive\InvalidPath" "ArchiveCmdletPathNotFound,Compress-Archive" + CompressArchiveInValidPathValidator "HKLM:\SOFTWARE" $TestDrive "HKLM:\SOFTWARE" "PathNotFound,Compress-Archive" + CompressArchiveInValidPathValidator "$TestDrive" "$TestDrive\NonExistingDirectory\sample.zip" "$TestDrive\NonExistingDirectory\sample.zip" "ArchiveCmdletPathNotFound,Compress-Archive" + + $path = @("$TestDrive", "$TestDrive\InvalidPath") + CompressArchiveInValidPathValidator $path $TestDrive "$TestDrive\InvalidPath" "ArchiveCmdletPathNotFound,Compress-Archive" + + $path = @("$TestDrive", "HKLM:\SOFTWARE") + CompressArchiveInValidPathValidator $path $TestDrive "HKLM:\SOFTWARE" "PathNotFound,Compress-Archive" + + $invalidUnZipFileFormat = "$TestDrive\Sample.unzip" + CompressArchiveInValidArchiveFileExtensionValidator $TestDrive "$invalidUnZipFileFormat" ".unzip" + + $invalidcabZipFileFormat = "$TestDrive\Sample.cab" + CompressArchiveInValidArchiveFileExtensionValidator $TestDrive "$invalidcabZipFileFormat" ".cab" + } + + It "Validate error from Compress-Archive when archive file already exists and -Update parameter is not specified" { + $sourcePath = "$TestDrive\SourceDir" + $destinationPath = "$TestDrive\ValidateErrorWhenUpdateNotSpecified.zip" + + try + { + "Some Data" > $destinationPath + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + throw "Failed to validate that an archive file format $destinationPath already exists and -Update switch parameter is not specified while running Compress-Archive command." + } + catch + { + $_.FullyQualifiedErrorId | Should Be "ArchiveFileExists,Compress-Archive" + } + } + + It "Validate error from Compress-Archive when duplicate paths are supplied as input to Path parameter" { + $sourcePath = @( + "$TestDrive\SourceDir\Sample-1.txt", + "$TestDrive\SourceDir\Sample-1.txt") + $destinationPath = "$TestDrive\DuplicatePaths.zip" + + try + { + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + throw "Failed to detect that duplicate Path $sourcePath is supplied as input to Path parameter." + } + catch + { + $_.FullyQualifiedErrorId | Should Be "DuplicatePathFound,Compress-Archive" + } + } + + It "Validate error from Compress-Archive when duplicate paths are supplied as input to LiteralPath parameter" { + $sourcePath = @( + "$TestDrive\SourceDir\Sample-1.txt", + "$TestDrive\SourceDir\Sample-1.txt") + $destinationPath = "$TestDrive\DuplicatePaths.zip" + + try + { + Compress-Archive -LiteralPath $sourcePath -DestinationPath $destinationPath + throw "Failed to detect that duplicate Path $sourcePath is supplied as input to LiteralPath parameter." + } + catch + { + $_.FullyQualifiedErrorId | Should Be "DuplicatePathFound,Compress-Archive" + } + } + } + + Context "Compress-Archive - functional test cases" { + It "Validate that a single file can be compressed using Compress-Archive cmdlet" { + $sourcePath = "$TestDrive\SourceDir\ChildDir-1\Sample-3.txt" + $destinationPath = "$TestDrive\SampleSingleFile.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + $destinationPath | Should Exist + } + # This test requires a fix in PS5 to support reading paths with square bracket + It "Validate that Compress-Archive cmdlet can accept LiteralPath parameter with Special Characters" -skip:($PSVersionTable.psversion -lt "5.0") { + $sourcePath = "$TestDrive\SourceDir\ChildDir-1\Sample[]File.txt" + "Some Random Content" | Out-File -LiteralPath $sourcePath + $destinationPath = "$TestDrive\SampleSingleFileWithSpecialCharacters.zip" + try + { + Compress-Archive -LiteralPath $sourcePath -DestinationPath $destinationPath + $destinationPath | Should Exist + } + finally + { + Remove-Item -LiteralPath $sourcePath -Force + } + } + It "Validate that Compress-Archive cmdlet errors out when DestinationPath resolves to multiple locations" { + + New-Item $TestDrive\SampleDir\Child-1 -Type Directory -Force | Out-Null + New-Item $TestDrive\SampleDir\Child-2 -Type Directory -Force | Out-Null + New-Item $TestDrive\SampleDir\Test.txt -Type File -Force | Out-Null + + $destinationPath = "$TestDrive\SampleDir\Child-*\SampleChidArchive.zip" + $sourcePath = "$TestDrive\SampleDir\Test.txt" + try + { + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + throw "Failed to detect that destination $destinationPath can resolve to multiple paths" + } + catch + { + $_.FullyQualifiedErrorId | Should Be "InvalidArchiveFilePath,Compress-Archive" + } + finally + { + Remove-Item -LiteralPath $TestDrive\SampleDir -Force -Recurse + } + } + It "Validate that Compress-Archive cmdlet works when DestinationPath has wild card pattern and resolves to a single valid path" { + + New-Item $TestDrive\SampleDir\Child-1 -Type Directory -Force | Out-Null + New-Item $TestDrive\SampleDir\Test.txt -Type File -Force | Out-Null + + $destinationPath = "$TestDrive\SampleDir\Child-*\SampleChidArchive.zip" + $sourcePath = "$TestDrive\SampleDir\Test.txt" + try + { + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + $destinationPath | Should Exist + } + finally + { + Remove-Item -LiteralPath $TestDrive\SampleDir -Force -Recurse + } + } + # This test requires a fix in PS5 to support reading paths with square bracket + It "Validate that Compress-Archive cmdlet can accept LiteralPath parameter for a directory with Special Characters in the directory name" -skip:($PSVersionTable.psversion -lt "5.0") { + $sourcePath = "$TestDrive\Source[]Dir\ChildDir[]-1" + New-Item $sourcePath -Type Directory | Out-Null + "Some Random Content" | Out-File -LiteralPath "$sourcePath\Sample[]File.txt" + $destinationPath = "$TestDrive\SampleDirWithSpecialCharacters.zip" + try + { + Compress-Archive -LiteralPath $sourcePath -DestinationPath $destinationPath + $destinationPath | Should Exist + } + finally + { + Remove-Item -LiteralPath $sourcePath -Force -Recurse + } + } + It "Validate that Compress-Archive cmdlet can accept DestinationPath parameter with Special Characters" { + $sourcePath = "$TestDrive\SourceDir\ChildDir-1\Sample-3.txt" + $destinationPath = "$TestDrive\Sample[]SingleFile.zip" + try + { + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path -LiteralPath $destinationPath | Should Be $true + } + finally + { + Remove-Item -LiteralPath $destinationPath -Force + } + } + It "Validate that Source Path can be at SystemDrive location" { + $sourcePath = "$env:SystemDrive\SourceDir" + $destinationPath = "$TestDrive\SampleFromSystemDrive.zip" + New-Item $sourcePath -Type Directory | Out-Null + "Some Data" | Out-File -FilePath $sourcePath\SampleSourceFileForArchive.txt + try + { + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + } + finally + { + del "$sourcePath" -Force -Recurse -ErrorAction SilentlyContinue + } + } + It "Validate that multiple files can be compressed using Compress-Archive cmdlet" { + $sourcePath = @( + "$TestDrive\SourceDir\ChildDir-1\Sample-3.txt", + "$TestDrive\SourceDir\ChildDir-1\Sample-4.txt", + "$TestDrive\SourceDir\ChildDir-2\Sample-5.txt", + "$TestDrive\SourceDir\ChildDir-2\Sample-6.txt") + $destinationPath = "$TestDrive\SampleMultipleFiles.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + } + It "Validate that multiple files and directories can be compressed using Compress-Archive cmdlet" { + $sourcePath = @( + "$TestDrive\SourceDir\Sample-1.txt", + "$TestDrive\SourceDir\Sample-2.txt", + "$TestDrive\SourceDir\ChildDir-1", + "$TestDrive\SourceDir\ChildDir-2") + $destinationPath = "$TestDrive\SampleMultipleFilesAndDirs.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + } + It "Validate that a single directory can be compressed using Compress-Archive cmdlet" { + $sourcePath = @("$TestDrive\SourceDir\ChildDir-1") + $destinationPath = "$TestDrive\SampleSingleDir.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + } + It "Validate that a single directory with multiple files and subdirectories can be compressed using Compress-Archive cmdlet" { + $sourcePath = @("$TestDrive\SourceDir") + $destinationPath = "$TestDrive\SampleSubTree.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + } + It "Validate that a single directory & multiple files can be compressed using Compress-Archive cmdlet" { + $sourcePath = @( + "$TestDrive\SourceDir\ChildDir-1", + "$TestDrive\SourceDir\Sample-1.txt", + "$TestDrive\SourceDir\Sample-2.txt") + $destinationPath = "$TestDrive\SampleMultipleFilesAndSingleDir.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + } + + It "Validate that if .zip extension is not supplied as input to DestinationPath parameter, then .zip extension is appended" { + $sourcePath = @("$TestDrive\SourceDir") + $destinationPath = "$TestDrive\SampleNoExtension.zip" + $destinationWithoutExtensionPath = "$TestDrive\SampleNoExtension" + Compress-Archive -Path $sourcePath -DestinationPath $destinationWithoutExtensionPath + Test-Path $destinationPath | Should Be $true + } + It "Validate that relative path can be specified as Path parameter of Compress-Archive cmdlet" { + $sourcePath = ".\SourceDir" + $destinationPath = "RelativePathForPathParameter.zip" + try + { + Push-Location $TestDrive + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + } + finally + { + Pop-Location + } + } + It "Validate that relative path can be specified as LiteralPath parameter of Compress-Archive cmdlet" { + $sourcePath = ".\SourceDir" + $destinationPath = "RelativePathForLiteralPathParameter.zip" + try + { + Push-Location $TestDrive + Compress-Archive -LiteralPath $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + } + finally + { + Pop-Location + } + } + It "Validate that relative path can be specified as DestinationPath parameter of Compress-Archive cmdlet" { + $sourcePath = "$TestDrive\SourceDir" + $destinationPath = ".\RelativePathForDestinationPathParameter.zip" + try + { + Push-Location $TestDrive + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + } + finally + { + Pop-Location + } + } + It "Validate that -Update parameter makes Compress-Archive to not throw an error if archive file already exists" { + $sourcePath = @("$TestDrive\SourceDir") + $destinationPath = "$TestDrive\SampleUpdateTest.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath -Update + Test-Path $destinationPath | Should Be $true + } + It "Validate -Update parameter by adding a new file to an existing archive file" { + $sourcePath = @("$TestDrive\SourceDir\ChildDir-1") + $destinationPath = "$TestDrive\SampleUpdateAdd1File.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + New-Item $TestDrive\SourceDir\ChildDir-1\Sample-AddedNewFile.txt -Type File | Out-Null + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath -Update + Test-Path $destinationPath | Should Be $true + Validate-ArchiveEntryCount -path $destinationPath -expectedEntryCount 3 + } + + It "Validate that all CompressionLevel values can be used with Compress-Archive cmdlet" { + $sourcePath = "$TestDrive\SourceDir\Sample-1.txt" + + $destinationPath = "$TestDrive\FastestCompressionLevel.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath -CompressionLevel Fastest + Test-Path $destinationPath | Should Be $true + + $destinationPath = "$TestDrive\OptimalCompressionLevel.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath -CompressionLevel Optimal + Test-Path $destinationPath | Should Be $true + + $destinationPath = "$TestDrive\NoCompressionCompressionLevel.zip" + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath -CompressionLevel NoCompression + Test-Path $destinationPath | Should Be $true + } + + It "Validate that -Update parameter is modifying a file that already exists in the archive file" { + $filePath = "$TestDrive\SourceDir\ChildDir-1\Sample-3.txt" + + $initialContent = "Initial Content" + $modifiedContent = "Modified Content" + + $initialContent | Set-Content $filePath + + $sourcePath = "$TestDrive\SourceDir" + $destinationPath = "$TestDrive\UpdatingModifiedFile.zip" + + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $True + + $modifiedContent | Set-Content $filePath + + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath -Update + Test-Path $destinationPath | Should Be $True + + ArchiveFileEntryContentValidator "$destinationPath" "SourceDir\ChildDir-1\Sample-3.txt" $modifiedContent + } + + It "Validate Compress-Archive cmdlet in pipleline scenario" { + $destinationPath = "$TestDrive\CompressArchiveFromPipeline.zip" + + # Piping a single file path to Compress-Archive + dir -Path $TestDrive\SourceDir\Sample-1.txt | Compress-Archive -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $True + + # Piping a string directory path to Compress-Archive + "$TestDrive\SourceDir\ChildDir-2" | Compress-Archive -DestinationPath $destinationPath -Update + Test-Path $destinationPath | Should Be $True + + # Piping the output of Get-ChildItem to Compress-Archive + dir "$TestDrive\SourceDir" -Recurse | Compress-Archive -DestinationPath $destinationPath -Update + Test-Path $destinationPath | Should Be $True + } + + It "Validate that Compress-Archive works on ReadOnly files" { + $sourcePath = "$TestDrive\ReadOnlyFile.txt" + $destinationPath = "$TestDrive\TestForReadOnlyFile.zip" + + "Some Content" | Out-File -FilePath $sourcePath + $createdItem = Get-Item $sourcePath + $createdItem.Attributes = 'ReadOnly' + + Compress-Archive -Path $sourcePath -DestinationPath $destinationPath + Test-Path $destinationPath | Should Be $true + } + + It "Validate that Compress-Archive generates Verbose messages" { + $sourcePath = "$TestDrive\SourceDir" + $destinationPath = "$TestDrive\Compress-Archive generates VerboseMessages.zip" + + try + { + $ps=[PowerShell]::Create() + $ps.Streams.Error.Clear() + $ps.Streams.Verbose.Clear() + $script = "Import-Module Microsoft.PowerShell.Archive; Compress-Archive -Path $sourcePath -DestinationPath `"$destinationPath`" -CompressionLevel Fastest -Verbose" + $ps.AddScript($script) + $ps.Invoke() + + $ps.Streams.Verbose.Count -gt 0 | Should Be $True + $ps.Streams.Error.Count | Should Be 0 + } + finally + { + $ps.Dispose() + } + } + } + + Context "Expand-Archive - Parameter validation test cases" { + It "Validate non existing archive -Path trows expected error message" { + $sourcePath = "$TestDrive\SourceDir" + $destinationPath = "$TestDrive\ExpandedArchive" + try + { + Expand-Archive -Path $sourcePath -DestinationPath $destinationPath + throw "Expand-Archive succeeded for non existing archive path" + } + catch + { + $_.FullyQualifiedErrorId | Should Be "PathNotFound,Expand-Archive" + } + } + + It "Validate errors from Expand-Archive with NULL & EMPTY values for Path, LiteralPath, DestinationPath parameters" { + ExpandArchiveInvalidParameterValidator $false $null "$TestDrive\SourceDir" "ParameterArgumentValidationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $false $null $null "ParameterArgumentValidationError,Expand-Archive" + + ExpandArchiveInvalidParameterValidator $false "$TestDrive\SourceDir" $null "ParameterArgumentTransformationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $false "" "$TestDrive\SourceDir" "ParameterArgumentTransformationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $false "$TestDrive\SourceDir" "" "ParameterArgumentTransformationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $false "" "" "ParameterArgumentTransformationError,Expand-Archive" + + ExpandArchiveInvalidParameterValidator $true $null "$TestDrive\SourceDir" "ParameterArgumentValidationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $true $null $null "ParameterArgumentValidationError,Expand-Archive" + + ExpandArchiveInvalidParameterValidator $true "$TestDrive\SourceDir" $null "ParameterArgumentValidationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $true "" "$TestDrive\SourceDir" "ParameterArgumentValidationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $true "$TestDrive\SourceDir" "" "ParameterArgumentValidationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $true "" "" "ParameterArgumentValidationError,Expand-Archive" + + ExpandArchiveInvalidParameterValidator $true $null "$TestDrive\SourceDir" "ParameterArgumentValidationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $true $null $null "ParameterArgumentValidationError,Expand-Archive" + + ExpandArchiveInvalidParameterValidator $true "$TestDrive\SourceDir" $null "ParameterArgumentValidationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $true "" "$TestDrive\SourceDir" "ParameterArgumentValidationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $true "$TestDrive\SourceDir" "" "ParameterArgumentValidationError,Expand-Archive" + ExpandArchiveInvalidParameterValidator $true "" "" "ParameterArgumentValidationError,Expand-Archive" + } + + It "Validate errors from Expand-Archive when invalid path (non-existing path / non-filesystem path) is supplied for Path or LiteralPath parameters" { + try { Expand-Archive -Path "$TestDrive\NonExistingArchive" -DestinationPath "$TestDrive\SourceDir"; throw "Expand-Archive did NOT throw expected error" } + catch { $_.FullyQualifiedErrorId | Should Be "ArchiveCmdletPathNotFound,Expand-Archive" } + + try { Expand-Archive -Path "HKLM:\SOFTWARE" -DestinationPath "$TestDrive\SourceDir"; throw "Expand-Archive did NOT throw expected error" } + catch { $_.FullyQualifiedErrorId | Should Be "PathNotFound,Expand-Archive" } + + try { Expand-Archive -LiteralPath "$TestDrive\NonExistingArchive" -DestinationPath "$TestDrive\SourceDir"; throw "Expand-Archive did NOT throw expected error" } + catch { $_.FullyQualifiedErrorId | Should Be "ArchiveCmdletPathNotFound,Expand-Archive" } + + try { Expand-Archive -LiteralPath "HKLM:\SOFTWARE" -DestinationPath "$TestDrive\SourceDir"; throw "Expand-Archive did NOT throw expected error" } + catch { $_.FullyQualifiedErrorId | Should Be "PathNotFound,Expand-Archive" } + } + + It "Validate error from Expand-Archive when invalid path (non-existing path / non-filesystem path) is supplied for DestinationPath parameter" { + $sourcePath = "$TestDrive\SamplePreCreatedArchive.zip" + $destinationPath = "HKLM:\SOFTWARE" + + try { Expand-Archive -Path $sourcePath -DestinationPath $destinationPath; throw "Expand-Archive did NOT throw expected error" } + catch { $_.FullyQualifiedErrorId | Should Be "InvalidDirectoryPath,Expand-Archive" } + } + } + + Context "Expand-Archive - functional test cases" { + + It "Validate basic Expand-Archive scenario" { + $sourcePath = "$TestDrive\SamplePreCreatedArchive.zip" + $content = "Some Data" + $destinationPath = "$TestDrive\DestDirForBasicExpand" + $files = @("Sample-1.txt", "Sample-2.txt") + + # The files in "$TestDrive\SamplePreCreatedArchive.zip" are precreated. + $fileCreationTimeStamp = Get-Date -Year 2014 -Month 6 -Day 13 -Hour 15 -Minute 50 -Second 20 -Millisecond 0 + + Expand-Archive -Path $sourcePath -DestinationPath $destinationPath + foreach($currentFile in $files) + { + $expandedFile = Join-Path $destinationPath -ChildPath $currentFile + Test-Path $expandedFile | Should Be $True + + # We are validating to make sure that time stamps are preserved in the + # compressed archive are reflected back when the file is expanded. + (dir $expandedFile).LastWriteTime.CompareTo($fileCreationTimeStamp) | Should Be 0 + + Get-Content $expandedFile | Should Be $content + } + } + It "Validate that Expand-Archive cmdlet errors out when DestinationPath resolves to multiple locations" { + New-Item $TestDrive\SampleDir\Child-1 -Type Directory -Force | Out-Null + New-Item $TestDrive\SampleDir\Child-2 -Type Directory -Force | Out-Null + + $destinationPath = "$TestDrive\SampleDir\Child-*" + $sourcePath = "$TestDrive\SamplePreCreatedArchive.zip" + try + { + Expand-Archive -Path $sourcePath -DestinationPath $destinationPath + throw "Failed to detect that destination $destinationPath can resolve to multiple paths" + } + catch + { + $_.FullyQualifiedErrorId | Should Be "InvalidDestinationPath,Expand-Archive" + } + finally + { + Remove-Item -LiteralPath $TestDrive\SampleDir -Force -Recurse + } + } + It "Validate that Expand-Archive cmdlet works when DestinationPath resolves has wild card pattern and resolves to a single valid path" { + New-Item $TestDrive\SampleDir\Child-1 -Type Directory -Force | Out-Null + + $destinationPath = "$TestDrive\SampleDir\Child-*" + $sourcePath = "$TestDrive\SamplePreCreatedArchive.zip" + try + { + Expand-Archive -Path $sourcePath -DestinationPath $destinationPath + $expandedFiles = Get-ChildItem $destinationPath -Recurse + $expandedFiles.Length | Should BeGreaterThan 1 + } + finally + { + Remove-Item -LiteralPath $TestDrive\SampleDir -Force -Recurse + } + } + It "Validate Expand-Archive scenario where DestinationPath has Special Characters" { + $sourcePath = "$TestDrive\SamplePreCreatedArchive.zip" + $content = "Some Data" + $destinationPath = "$TestDrive\DestDir[]Expand" + $files = @("Sample-1.txt", "Sample-2.txt") + + # The files in "$TestDrive\SamplePreCreatedArchive.zip" are precreated. + $fileCreationTimeStamp = Get-Date -Year 2014 -Month 6 -Day 13 -Hour 15 -Minute 50 -Second 20 -Millisecond 0 + + Expand-Archive -Path $sourcePath -DestinationPath $destinationPath + foreach($currentFile in $files) + { + $expandedFile = Join-Path $destinationPath -ChildPath $currentFile + Test-Path -LiteralPath $expandedFile | Should Be $True + + # We are validating to make sure that time stamps are preserved in the + # compressed archive are reflected back when the file is expanded. + (dir -LiteralPath $expandedFile).LastWriteTime.CompareTo($fileCreationTimeStamp) | Should Be 0 + + Get-Content -LiteralPath $expandedFile | Should Be $content + } + } + It "Invoke Expand-Archive with relative path in Path parameter and -Force parameter" { + $sourcePath = ".\SamplePreCreatedArchive.zip" + $destinationPath = "$TestDrive\SomeOtherNonExistingDir\Path" + try + { + Push-Location $TestDrive + + Expand-Archive -Path $sourcePath -DestinationPath $destinationPath -Force + $expandedFiles = Get-ChildItem $destinationPath -Recurse + $expandedFiles.Length | Should Be 2 + } + finally + { + Pop-Location + } + } + + It "Invoke Expand-Archive with relative path in LiteralPath parameter and -Force parameter" { + $sourcePath = ".\SamplePreCreatedArchive.zip" + $destinationPath = "$TestDrive\SomeOtherNonExistingDir\LiteralPath" + try + { + Push-Location $TestDrive + + Expand-Archive -LiteralPath $sourcePath -DestinationPath $destinationPath -Force + $expandedFiles = Get-ChildItem $destinationPath -Recurse + $expandedFiles.Length | Should Be 2 + } + finally + { + Pop-Location + } + } + + It "Invoke Expand-Archive with non-existing relative directory in DestinationPath parameter and -Force parameter" { + $sourcePath = "$TestDrive\SamplePreCreatedArchive.zip" + $destinationPath = ".\SomeOtherNonExistingDir\DestinationPath" + try + { + Push-Location $TestDrive + + Expand-Archive -Path $sourcePath -DestinationPath $destinationPath -Force + $expandedFiles = Get-ChildItem $destinationPath -Recurse + $expandedFiles.Length | Should Be 2 + } + finally + { + Pop-Location + } + } + + It "Invoke Expand-Archive with unsupported archive format" { + $sourcePath = "$TestDrive\Sample.cab" + $destinationPath = "$TestDrive\UnsupportedArchiveFormatDir" + try + { + Expand-Archive -Path $sourcePath -DestinationPath $destinationPath -Force + throw "Failed to detect unsupported archive format at $sourcePath" + } + catch + { + $_.FullyQualifiedErrorId | Should Be "NotSupportedArchiveFileExtension,Expand-Archive" + } + } + + It "Invoke Expand-Archive with archive file containing multiple files, directories with subdirectories and empty directories" { + $sourcePath = "$TestDrive\SourceDir" + $archivePath = "$TestDrive\FileAndDirTreeForExpand.zip" + $destinationPath = "$TestDrive\FileAndDirTree" + $sourceList = dir $sourcePath -Name + + Add-CompressionAssemblies + [System.IO.Compression.ZipFile]::CreateFromDirectory($sourcePath, $archivePath) + + Expand-Archive -Path $archivePath -DestinationPath $destinationPath + $extractedList = dir $destinationPath -Name + + Compare-Object -ReferenceObject $extractedList -DifferenceObject $sourceList -PassThru | Should Be $null + } + + It "Validate Expand-Archive cmdlet in pipleline scenario" { + $sourcePath = "$TestDrive\SamplePreCreated*.zip" + $destinationPath = "$TestDrive\PipeToExpandArchive" + + $content = "Some Data" + $files = @("Sample-1.txt", "Sample-2.txt") + + dir $sourcePath | Expand-Archive -DestinationPath $destinationPath + + foreach($currentFile in $files) + { + $expandedFile = Join-Path $destinationPath -ChildPath $currentFile + Test-Path $expandedFile | Should Be $True + Get-Content $expandedFile | Should Be $content + } + } + + It "Validate that Expand-Archive generates Verbose messages" { + $sourcePath = "$TestDrive\SamplePreCreatedArchive.zip" + $destinationPath = "$TestDrive\VerboseMessagesInExpandArchive" + + try + { + $ps=[PowerShell]::Create() + $ps.Streams.Error.Clear() + $ps.Streams.Verbose.Clear() + $script = "Import-Module Microsoft.PowerShell.Archive; Expand-Archive -Path $sourcePath -DestinationPath $destinationPath -Verbose" + $ps.AddScript($script) + $ps.Invoke() + + $ps.Streams.Verbose.Count -gt 0 | Should Be $True + $ps.Streams.Error.Count | Should Be 0 + } + finally + { + $ps.Dispose() + } + } + + It "Validate that without -Force parameter Expand-Archive generates non-terminating errors without overwriting existing files" { + $sourcePath = "$TestDrive\SamplePreCreatedArchive.zip" + $destinationPath = "$TestDrive\NoForceParameterExpandArchive" + + try + { + $ps=[PowerShell]::Create() + $ps.Streams.Error.Clear() + $ps.Streams.Verbose.Clear() + $script = "Import-Module Microsoft.PowerShell.Archive; Expand-Archive -Path $sourcePath -DestinationPath $destinationPath; Expand-Archive -Path $sourcePath -DestinationPath $destinationPath" + $ps.AddScript($script) + $ps.Invoke() + + $ps.Streams.Error.Count -gt 0 | Should Be $True + } + finally + { + $ps.Dispose() + } + } + + It "Validate that without DestinationPath parameter Expand-Archive cmdlet succeeds in expanding the archive" { + $sourcePath = "$TestDrive\SamplePreCreatedArchive.zip" + $archivePath = "$TestDrive\NoDestinationPathParameter.zip" + $destinationPath = "$TestDrive\NoDestinationPathParameter" + copy $sourcePath $archivePath -Force + + try + { + Push-Location $TestDrive + + Expand-Archive -Path $archivePath + (dir $destinationPath).Count | Should Be 2 + } + finally + { + Pop-Location + } + } + + It "Validate that without DestinationPath parameter Expand-Archive cmdlet succeeds in expanding the archive when destination directory exists" { + $sourcePath = "$TestDrive\SamplePreCreatedArchive.zip" + $archivePath = "$TestDrive\NoDestinationPathParameterDirExists.zip" + $destinationPath = "$TestDrive\NoDestinationPathParameterDirExists" + copy $sourcePath $archivePath -Force + New-Item -Path $destinationPath -ItemType Directory | Out-Null + + try + { + Push-Location $TestDrive + + Expand-Archive -Path $archivePath + (dir $destinationPath).Count | Should Be 2 + } + finally + { + Pop-Location + } + } + } +} \ No newline at end of file diff --git a/test/powershell/Modules/Microsoft.PowerShell.Archive/SamplePreCreatedArchive.archive b/test/powershell/Modules/Microsoft.PowerShell.Archive/SamplePreCreatedArchive.archive new file mode 100644 index 0000000000000000000000000000000000000000..c2aecb417985e0ae3b2fff30c1cfd41f82be5932 GIT binary patch literal 270 zcmWIWW@Zs#U|`^2@TxoOvPh-fTmr}gVICk3PRuRHN!2yfE2${?{a=5E;(W#Fic=jM z54I{!T*%T + + if (test-path $testDirectory) + { + Remove-Item $testDirectory -Force -ea SilentlyContinue -Recurse + } + + # Create testDirectory, and destinationDirectory + New-Item $testDirectory -ItemType Directory -Force | Out-Null + New-Item $destinationDirectory -ItemType Directory -Force | Out-Null + } + + Context "Validate Copy-Item Locally." { + It "Copy-Item -Path $filePath -Destination $destinationFolderPath" { + + $filePath = CreateTestFile + $destinationFolderPath = GetDestinationFolderPath + Copy-Item -Path $filePath -Destination $destinationFolderPath + ValidateCopyItemOperation -filePath $filePath + } + + It "Copy-Item -Path $($testObject.SourceDirectory) -Destination $destinationFolderPath -Recurse" { + + $testObject = CreateTestDirectory + $destinationFolderPath = GetDestinationFolderPath + Copy-Item -Path $testObject.SourceDirectory -Destination $destinationFolderPath -Recurse + foreach ($file in $testObject.Files) + { + $copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\SourceDirectory") + $copiedFilePath | should Exist + } + } + } + + Context "Validate Copy-Item to remote session." { + + It "Copy one file to remote session." { + $filePath = CreateTestFile + $destinationFolderPath = GetDestinationFolderPath + Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath + ValidateCopyItemOperation -filePath $filePath + } + + It "Copy one read only file to remote session." { + + $filePath = CreateTestFile -setReadOnlyAttribute + $destinationFolderPath = GetDestinationFolderPath + Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath -Force + ValidateCopyItemOperation -filePath $filePath + } + + It "Copy-Item works for a read only file when '-Force' is not used." { + + $filePath = CreateTestFile -setReadOnlyAttribute + $destinationFolderPath = GetDestinationFolderPath + Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath -Verbose + ValidateCopyItemOperation -filePath $filePath + } + + It "Copy one folder to session Recursively" { + + $testObject = CreateTestDirectory + $destinationFolderPath = GetDestinationFolderPath + Copy-Item -Path $testObject.SourceDirectory -ToSession $s -Destination $destinationFolderPath -Recurse + + foreach ($file in $testObject.Files) + { + $copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\SourceDirectory") + $copiedFilePath | should Exist + (Get-Item $copiedFilePath).Length | should be (Get-Item $file).Length + } + } + + It "Copy folder with read only files to remote session recursively." { + $testObject = CreateTestDirectory -setReadOnlyAttribute + $destinationFolderPath = GetDestinationFolderPath + Copy-Item -Path $testObject.SourceDirectory -ToSession $s -Destination $destinationFolderPath -Recurse -Force + + foreach ($file in $testObject.Files) + { + $copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\SourceDirectory") + $copiedFilePath | should Exist + (Get-Item $copiedFilePath).Length | should be (Get-Item $file).Length + } + } + + It "Copy one file to remote session fails when the remote directory does not exist." { + + $filePath = CreateTestFile + $destinationFolderPath = GetDestinationFolderPath + $destinationFolderPath = Join-Path $destinationFolderPath "A\B\C\D\E" + $expectedFullyQualifiedErrorId = 'RemotePathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand' + + try + { + Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath -ErrorAction Stop + throw "CodeExecuted" + } + catch + { + $_.FullyQualifiedErrorId | should be $expectedFullyQualifiedErrorId + } + } + + It "Copy folder to remote session recursively works even if the target directory does not exist." { + $testObject = CreateTestDirectory -setReadOnlyAttribute + $destinationFolderPath = GetDestinationFolderPath + $destinationFolderPath = Join-Path $destinationFolderPath "FoderThatDoesNotExist" + Copy-Item -Path $testObject.SourceDirectory -ToSession $s -Destination $destinationFolderPath -Recurse -Force + + foreach ($file in $testObject.Files) + { + $copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\FoderThatDoesNotExist") + $copiedFilePath | should Exist + (Get-Item $copiedFilePath).Length | should be (Get-Item $file).Length + } + } + + It "Copy one empty file to remote session." { + + $filePath = CreateTestFile -emptyFile + $destinationFolderPath = GetDestinationFolderPath + $copiedFilePath = ([string]$filePath).Replace("SourceDirectory", "DestinationDirectory") + $copiedFilePath | should Not Exist + Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath + $copiedFilePath | should Exist + (Get-Item $copiedFilePath).Length | should be (Get-Item $filePath).Length + } + + It "Copy-Item to session supports alternate data streams." { + + $filePath = CreateTestFile + $destinationFolderPath = GetDestinationFolderPath + $streamContent = "This content is hidden" + $streamName = "Hidden" + Set-Content -Path $filePath -Value $streamContent -Stream $streamName + Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath -Verbose + ValidateCopyItemOperationForAlternateDataStream -filePath $filePath -streamName $streamName -expectedStreamContent $streamContent + } + } + + Context "Validate Copy-Item from remote session." { + + It "Copy one file from remote session." { + + $filePath = CreateTestFile + $destinationFolderPath = GetDestinationFolderPath + $copiedFilePath = ([string]$filePath).Replace("SourceDirectory", "DestinationDirectory") + $copiedFilePath | should Not Exist + Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath + ValidateCopyItemOperation -filePath $filePath + } + + It "Copy one empty file from remote session." { + + $filePath = CreateTestFile -emptyFile + $destinationFolderPath = GetDestinationFolderPath + $copiedFilePath = ([string]$filePath).Replace("SourceDirectory", "DestinationDirectory") + $copiedFilePath | should Not Exist + Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath + ValidateCopyItemOperation -filePath $filePath + } + + It "Copy folder from remote session recursively." { + + $testObject = CreateTestDirectory + $destinationFolderPath = GetDestinationFolderPath + $files = @(Get-ChildItem $destinationFolderPath -Recurse -Force) + Copy-Item -Path $testObject.SourceDirectory -FromSession $s -Destination $destinationFolderPath -Recurse + + foreach ($file in $testObject.Files) + { + $copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\SourceDirectory") + $copiedFilePath | should Exist + (Get-Item $copiedFilePath).Length | should be (Get-Item $file).Length + } + } + + It "Copy one file from remote session fails when the target directory does not exist." { + + $filePath = CreateTestFile + $destinationFolderPath = GetDestinationFolderPath + $destinationFolderPath = Join-Path $destinationFolderPath "A\B\C\D\E" + $expectedFullyQualifiedErrorId = 'CopyItemRemotelyIOError,Microsoft.PowerShell.Commands.CopyItemCommand' + try + { + Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath -ErrorAction Stop + throw "CodeExecuted" + } + catch + { + $_.FullyQualifiedErrorId | should be $expectedFullyQualifiedErrorId + } + } + + It "Copy folder from remote session recursively works even if the target directory does not exist." { + + $testObject = CreateTestDirectory + $destinationFolderPath = GetDestinationFolderPath + $destinationFolderPath = Join-Path $destinationFolderPath "FoderThatDoesNotExist" + $files = @(Get-ChildItem $destinationFolderPath -Recurse -Force) + Copy-Item -Path $testObject.SourceDirectory -FromSession $s -Destination $destinationFolderPath -Recurse + + foreach ($file in $testObject.Files) + { + $copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\FoderThatDoesNotExist") + $copiedFilePath | should Exist + (Get-Item $copiedFilePath).Length | should be (Get-Item $file).Length + } + } + + It "Copy a read only file from a remote session." { + + $filePath = CreateTestFile -setReadOnlyAttribute + $destinationFolderPath = GetDestinationFolderPath + $copiedFilePath = ([string]$filePath).Replace("SourceDirectory", "DestinationDirectory") + Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath -Force + ValidateCopyItemOperation -filePath $filePath + } + + It "Copy-Item for a read only file works with no '-force' parameter." { + + $filePath = CreateTestFile -setReadOnlyAttribute + $destinationFolderPath = GetDestinationFolderPath + Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath + ValidateCopyItemOperation -filePath $filePath + } + + It "Copy-Item -FromSession works even when trying to copy an assembly that is currently being used by another process." { + + $testAssembly = GenerateTestAssembly + $destinationFolderPath = GetDestinationFolderPath + Import-Module $testAssembly.Path -Force + try + { + Copy-Item -Path $testAssembly.Path -FromSession $s -Destination $destinationFolderPath + ValidateCopyItemOperation -filePath $testAssembly.Path + } + finally + { + Remove-Module $testAssembly.ModuleName -Force -ea SilentlyContinue + } + } + + It "Copy-Item from session supports alternate data streams." { + + $filePath = CreateTestFile + $destinationFolderPath = GetDestinationFolderPath + $streamContent = "This content is hidden" + $streamName = "Hidden" + Set-Content -Path $filePath -Value $streamContent -Stream $streamName + Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath + ValidateCopyItemOperationForAlternateDataStream -filePath $filePath -streamName $streamName -expectedStreamContent $streamContent + } + } + + Context "Validate Copy-Item Remotely using wildcards" { + + It "Copy-Item from session using wildcards." { + + $testObject = CreateTestDirectory + $destinationFolderPath = GetDestinationFolderPath + $sourcePathWithWildcards = "$($testObject.SourceDirectory)\A\*.txt" + Copy-Item -Path $sourcePathWithWildcards -FromSession $s -Destination $destinationFolderPath -Force + + $sourceFiles = @(Get-Item $sourcePathWithWildcards) + foreach ($file in $sourceFiles) + { + $copiedFilePath = Join-Path $destinationFolderPath (Split-Path $file -Leaf) + $copiedFilePath | Should Exist + (Get-Item $copiedFilePath).Length | Should Be (Get-Item $file).Length + } + } + + It "Copy-Item to session using wildcards." { + + $testObject = CreateTestDirectory + $destinationFolderPath = GetDestinationFolderPath + $sourcePathWithWildcards = "$($testObject.SourceDirectory)\A\*.txt" + Copy-Item -Path $sourcePathWithWildcards -ToSession $s -Destination $destinationFolderPath -Force + + $sourceFiles = @(Get-Item $sourcePathWithWildcards) + foreach ($file in $sourceFiles) + { + $copiedFilePath = Join-Path $destinationFolderPath (Split-Path $file -Leaf) + $copiedFilePath | Should Exist + (Get-Item $copiedFilePath).Length | Should Be (Get-Item $file).Length + } + } + } + + Context "Validate FullyQualifiedErrorIds for remote source and destination paths." { + + BeforeAll { + # Create test file. + $testFilePath = Join-Path "TestDrive:" "testfile.txt" + if (test-path $testFilePath) + { + Remove-Item $testFilePath -Force -ea SilentlyContinue + } + "File test content" | Out-File $testFilePath -Force + } + + function Test-CopyItemError + { + param ($path, $destination, $expectedFullyQualifiedErrorId, $fromSession = $false) + + if ($fromSession) + { + It "Copy-Item FromSession -Path '$path' throws $expectedFullyQualifiedErrorId" { + try + { + Copy-Item -Path $path -FromSession $s -Destination $destination -ErrorAction Stop + throw "CodeExecuted" + } + catch + { + $_.FullyQualifiedErrorId | should be $expectedFullyQualifiedErrorId + } + } + } + else + { + It "Copy-Item ToSession -Destination '$path' throws $expectedFullyQualifiedErrorId" { + try + { + Copy-Item -Path $path -ToSession $s -Destination $destination -ErrorAction Stop + throw "CodeExecuted" + } + catch + { + $_.FullyQualifiedErrorId | should be $expectedFullyQualifiedErrorId + } + } + } + } + + $invalidSourcePathtestCases = @( + @{ + Path = "HKLM:\SOFTWARE" + Destination = $env:SystemDrive + ExpectedFullyQualifiedErrorId = "NamedParameterNotFound,Microsoft.PowerShell.Commands.CopyItemCommand" + FromSession = $true + } + @{ + Path = ".\Source" + Destination = $env:SystemDrive + ExpectedFullyQualifiedErrorId = "RemotePathIsNotAbsolute,Microsoft.PowerShell.Commands.CopyItemCommand" + FromSession = $true + } + @{ + Path = $env:SystemDrive + "\X\Y\Z" + Destination = $env:SystemDrive + "\A\B\C" + ExpectedFullyQualifiedErrorId = "RemotePathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand" + FromSession = $true + } + @{ + Path = $null + Destination = $env:SystemDrive + ExpectedFullyQualifiedErrorId = "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand" + FromSession = $true + } + @{ + Path = '' + Destination = $env:SystemDrive + ExpectedFullyQualifiedErrorId = "ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand" + FromSession = $true + } + @{ + Path = "$env:SystemDrive\nonexistdir\*" + Destination = "$env:SystemDrive\psTest" + ExpectedFullyQualifiedErrorId = "RemotePathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand" + FromSession = $true + } + ) + + foreach ($testCase in $invalidSourcePathtestCases) { + Test-CopyItemError @testCase + } + + $invalidDestinationPathtestCases = @( + @{ + Path = $testFilePath + Destination = ".\Source" + ExpectedFullyQualifiedErrorId = "RemotePathIsNotAbsolute,Microsoft.PowerShell.Commands.CopyItemCommand" + } + @{ + Path = $testFilePath + Destination = $env:SystemDrive + "\X\A\B\C" + ExpectedFullyQualifiedErrorId = "RemotePathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand" + } + @{ + Path = $testFilePath + Destination = $null + ExpectedFullyQualifiedErrorId = "CopyItemRemoteDestinationIsNullOrEmpty,Microsoft.PowerShell.Commands.CopyItemCommand" + } + @{ + Path = $testFilePath + Destination = "" + ExpectedFullyQualifiedErrorId = "CopyItemRemoteDestinationIsNullOrEmpty,Microsoft.PowerShell.Commands.CopyItemCommand" + } + @{ + Path = "$env:SystemDrive\nonexistdir\*" + Destination = "$env:SystemDrive\psTest" + ExpectedFullyQualifiedErrorId = "PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand" + } + ) + + foreach ($testCase in $invalidDestinationPathtestCases) { + Test-CopyItemError @testCase + } + } +} + +Describe "Validate Copy-Item error for target sessions not in FullLanguageMode." -Tags "Innerloop", "RI", "P1" { + + BeforeAll { + + $testDirectory = "TestDrive:\" + + # Create the test file and directories. + $source = "$testDirectory\Source" + $destination = "$testDirectory\Destination" + + New-Item $source -ItemType Directory -Force | Out-Null + New-Item $destination -ItemType Directory -Force | Out-Null + + $testFilePath = Join-Path $source "testfile.txt" + "File test content" | Out-File $testFilePath -Force + + # Keep track of the sessions. + $testSessions = @{} + + # Keep track of the session names to be unregistered. + $sessionToUnregister = @() + + $languageModes = @("ConstrainedLanguage", "NoLanguage", "RestrictedLanguage") + $id = (Get-Random).ToString() + + foreach ($languageMode in $languageModes) + { + $sessionName = $languageMode + "_" + $id + $sessionToUnregister += $sessionName + $configFilePath = Join-Path $testDirectory "test.pssc" + + # Create the session. + Write-Host "Creating pssession with '$languageMode' ..." + New-PSSessionConfigurationFile -Path $configFilePath -SessionType Default -LanguageMode $languageMode + Register-PSSessionConfiguration -Name $sessionName -Path $configFilePath -Force | Out-Null + $testSession = New-PSSession -ConfigurationName $sessionName + + # Validate that the session is opened. + $testSession.State | Should Be "Opened" + + # Add the new session to the list. + $testSessions[$languageMode] = $testSession + + # Remove the pssc file. + Remove-Item $configFilePath -Force -ea SilentlyContinue + } + } + + AfterAll { + + $testSessions.Values | Remove-PSSession -ea SilentlyContinue + + $sessionToUnregister | foreach { + Unregister-PSSessionConfiguration -Name $_ -Force -ea SilentlyContinue + } + } + + foreach ($languageMode in $testSessions.Keys) + { + $session = $testSessions[$languageMode] + + It "Copy-Item throws 'SessionIsNotInFullLanguageMode' error for a session in '$languageMode'" { + + # FromSession + try + { + Copy-Item -Path $testFilePath -FromSession $session -Destination $destination -Force -Verbose -ea Stop + throw "CodeExecuted" + } + catch + { + $_.FullyQualifiedErrorId | should be "SessionIsNotInFullLanguageMode,Microsoft.PowerShell.Commands.CopyItemCommand" + } + + # ToSession + try + { + Copy-Item -Path $testFilePath -ToSession $session -Destination $destination -Force -Verbose -ea Stop + throw "CodeExecuted" + } + catch + { + $_.FullyQualifiedErrorId | should be "SessionIsNotInFullLanguageMode,Microsoft.PowerShell.Commands.CopyItemCommand" + } + } + } +} + +Describe "Copy-Item can use Recurse and Exclude together" -Tags "RI", "P1" { + + Context "Local and Remote Tests" { + + BeforeAll { + $s = New-PSSession -ComputerName . -ea SilentlyContinue + if (-not $s) + { + throw "Failed to create PSSession for remote copy operations." + } + + $null = New-Item -ItemType Directory -Path "TestDrive:\Parent\Sub" + $null = New-Item -Path "TestDrive:\Parent\p1.txt" -Value "test" + $null = New-Item -Path "TestDrive:\Parent\p2.txt" -Value "test" + $null = New-Item -Path "TestDrive:\Parent\s4.txt" -Value "test" + $null = New-Item -Path "TestDrive:\Parent\Sub\s1.txt" -Value "test" + $null = New-Item -Path "TestDrive:\Parent\Sub\s2.txt" -Value "test" + $null = New-Item -Path "TestDrive:\Parent\Sub\s3.txt" -Value "test" + $null = New-Item -Path "TestDrive:\Parent\Sub\p3.txt" -Value "testcl" + } + + It "can exclude files at sub directory" { + Copy-Item -Path TestDrive:\Parent\* -Recurse -Exclude s*.txt -Destination TestDrive:\Temp -Force + $copiedFiles = Get-ChildItem -Recurse -Path TestDrive:\Temp + $copiedFiles.Count | Should Be 3 + } + + It "can exclude files at sub directory to a session" { + Copy-Item -Path TestDrive:\Parent\* -Recurse -Exclude s*.txt -Destination $TestDrive\Temp2 -Force -ToSession $s + $copiedFiles = Get-ChildItem -Recurse -Path TestDrive:\Temp + $copiedFiles.Count | Should Be 3 + } + + It "can exclude files at sub directory from a session" { + Copy-Item -Path $TestDrive\Parent\* -Recurse -Exclude s*.txt -Destination TestDrive:\Temp3 -FromSession $s + $copiedFiles = Get-ChildItem -Recurse -Path TestDrive:\Temp2 + $copiedFiles.Count | Should Be 3 + } + + AfterAll { + Remove-PSSession -Session $s -ErrorAction SilentlyContinue + } + } +} + +Describe "Copy-Item remotely bug fixes" -Tags "RI", "P1" { + + BeforeAll { + $s = New-PSSession -ComputerName . -ErrorAction SilentlyContinue + if (-not $s) + { + throw "Failed to create PSSession for remote copy operations." + } + + $originalContent = "test file 1 - Source" + $newContent = "This is some new content" + + $null = New-Item -ItemType Directory -Path "TestDrive:\Source" + $null = New-Item -ItemType Directory -Path "TestDrive:\Destination" + } + + AfterAll { + Remove-PSSession -Session $s -ErrorAction SilentlyContinue + } + + BeforeEach { + + # Create the same file in the source and destination + Set-Content -Path "TestDrive:\Source\testFile1.txt" -Value $originalContent -Force + Set-Content -Path "TestDrive:\Destination\testFile1.txt" -Value $originalContent -Force + } + + Context "Copy-Item remotely overwrites a destination file if it exists." { + + BeforeEach { + + # Overwrite the source file + Set-Content -Path "TestDrive:\Source\testFile1.txt" -Value $newContent + } + + It "Copy item -tosession overwrites the content of an existing file." { + + # Copy file to session + Copy-Item -Path "TestDrive:\Source\testFile1.txt" -Destination "$TestDrive\Destination\testFile1.txt" -ToSession $s + + # Validate the the file was overwritten + $fileContent = Get-Content "TestDrive:\Destination\testFile1.txt" -ea SilentlyContinue -Raw + $fileContent | Should Match $newContent + } + + It "Copy item -fromsession overwrites the content of an existing file." { + + # Copy file to session + Copy-Item -Path "$TestDrive\Source\testFile1.txt" -Destination "TestDrive:\Destination\testFile1.txt" -FromSession $s + + # Validate the the file was overwritten + $fileContent = Get-Content "TestDrive:\Destination\testFile1.txt" -ea SilentlyContinue -Raw + $fileContent | Should Match $newContent + } + } + + Context "Copy-Item remotely creates a destination file if it does not exist." { + + BeforeEach { + + if (Test-Path "TestDrive:\AnotherDestination") + { + Remove-Item "TestDrive:\AnotherDestination" -Force -Recurse -ea SilentlyContinue + } + $null = New-Item -ItemType Directory -Path "TestDrive:\AnotherDestination" + + # Ensure the file does not exist + "TestDrive:\AnotherDestination\FileThatDoesNotExist.txt" | Should Not Exist + } + + It "Copy-Item -tosession creates the file if it does not exist on the remote destination." { + + # Copy file to session + Copy-Item -Path "TestDrive:\Source\testFile1.txt" -Destination "$TestDrive\AnotherDestination\FileThatDoesNotExist.txt" -ToSession $s + + # Verify that the file was created + "TestDrive:\AnotherDestination\FileThatDoesNotExist.txt" | Should Exist + } + + It "Copy-Item -fromsession creates the file if it does not exist on the local machine." { + + # Copy file from session + Copy-Item -Path "$TestDrive\Source\testFile1.txt" -Destination "TestDrive:\AnotherDestination\FileThatDoesNotExist.txt" -FromSession $s + + # Verify that the file was created + "TestDrive:\AnotherDestination\FileThatDoesNotExist.txt" | Should Exist + } + } +} \ No newline at end of file diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Pester.Commands.Cmdlets.NoNewlineParameter.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Pester.Commands.Cmdlets.NoNewlineParameter.Tests.ps1 new file mode 100644 index 0000000000..420c2cfc2d --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Pester.Commands.Cmdlets.NoNewlineParameter.Tests.ps1 @@ -0,0 +1,26 @@ +# Tests related to TFS item 1370133 [PSUpgrade] Need -NoNewline parameter on Out-File, Add-Content and Set-Content +# Connect request https://connect.microsoft.com/PowerShell/feedback/details/524739/need-nonewline-parameter-on-out-file-add-content-and-set-content + +Describe "Tests for -NoNewline parameter of Out-File, Add-Content and Set-Content" -tags 'P1', 'RI' { + + It "NoNewline parameter works on Out-File" { + $temp = New-TemporaryFile + 1..5 | Out-File $temp.FullName -Encoding 'ASCII' -NoNewline + (Get-Content $temp -Encoding Byte).Count | Should Be 5 + Remove-Item $temp -ErrorAction SilentlyContinue -Force + } + + It "NoNewline parameter works on Set-Content" { + $temp = New-TemporaryFile + Set-Content -Path $temp.FullName -Value 'a','b','c' -Encoding 'ASCII' -NoNewline + (Get-Content $temp -Encoding Byte).Count | Should Be 3 + Remove-Item $temp -ErrorAction SilentlyContinue -Force + } + + It "NoNewline parameter works on Add-Content" { + $temp = New-TemporaryFile + 1..9 | %{Add-Content -Path $temp.FullName -Value $_ -Encoding 'ASCII' -NoNewline} + (Get-Content $temp -Encoding Byte).Count | Should Be 9 + Remove-Item $temp -ErrorAction SilentlyContinue -Force + } +} \ No newline at end of file diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/FormatHex.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/FormatHex.Tests.ps1 new file mode 100644 index 0000000000..91d05c78d3 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/FormatHex.Tests.ps1 @@ -0,0 +1,218 @@ +# This is a Pester test suite to validate the Format-Hex cmdlet in the Microsoft.PowerShell.Utility module. +# +# Copyright (c) Microsoft Corporation, 2015 +# + +<# + Purpose: + Verify that Format-Hex display the Hexa decmial value for the input data. + + Action: + Run Format-Fex. + + Expected Result: + Hexa decimal equivalent of the input data is displayed. +#> + +Describe "FormatHex" -tags 'DRT' { + + New-Item TestDrive:\FormatHexDataDir -Type Directory -Force | Out-Null + $inputFile = "TestDrive:\FormatHexDataDir\SourceFile-1.txt" + $inputText = 'Hello World' + Set-Content -Value $inputText -Path $inputFile + $inputFile2 = "TestDrive:\FormatHexDataDir\SourceFile-2.txt" + $inputText2 = 'This is a bit more text' + Set-Content -Value $inputText2 -Path $inputFile2 + + # This test is to validate to pipeline support in Format-Hex cmdlet. + It "ValidatePipelineSupport" { + + # InputObject Parameter set should get invoked and + # the input data should be treated as string. + $result = $inputText | Format-Hex + $result | Should Not Be $null + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + ($actualResult -match $inputText) | Should Be $true + } + + # This test is to validate to pipeline support in Format-Hex cmdlet. + It "ValidateByteArrayInputSupport" { + + # InputObject Parameter set should get invoked and + # the input data should be treated as byte[]. + $inputBytes = [System.Text.Encoding]::ASCII.GetBytes($inputText) + + $result = Format-Hex -InputObject $inputBytes + $result | Should Not Be $null + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + ($actualResult -match $inputText) | Should Be $true + } + + # This test is to validate to input given through Path paramter set in Format-Hex cmdlet. + It "ValidatePathParameterSet" { + + $result = Format-Hex -Path $inputFile + $result | Should Not Be $null + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + ($actualResult -match $inputText) | Should Be $true + } + + # This test is to validate to Path paramter set is considered as default in Format-Hex cmdlet. + It "ValidatePathAsDefaultParameterSet" { + + $result = Format-Hex $inputFile + $result | Should Not BeNullOrEmpty + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + ($actualResult -match $inputText) | Should Be $true + } + + # This test is to validate to input given through LiteralPath paramter set in Format-Hex cmdlet. + It "ValidateLiteralPathParameterSet" { + + $result = Format-Hex -LiteralPath $inputFile + $result | Should Not BeNullOrEmpty + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + ($actualResult -match $inputText) | Should Be $true + } + + # This test is to validate to input given through pipeline. The input being piped from results of Get-hildItem + It "ValidateFileInfoPipelineInput" { + + $result = Get-ChildItem $inputFile | Format-Hex + $result | Should Not BeNullOrEmpty + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + ($actualResult -match $inputText) | Should Be $true + } + + # This test is to validate Encoding formats functionality of Format-Hex cmdlet. + It "ValidateEncodingFormats" { + + $result = Format-Hex -InputObject $inputText -Encoding ASCII + $result | Should Not BeNullOrEmpty + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + ($actualResult -match $inputText) | Should Be $true + } + + # This test is to validate that integers can be piped to the format-hex + It "ValidateIntegerInput" { + + $result = 1,2,3,4 | Format-Hex + $result | Should Not BeNullOrEmpty + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + # whitespace sensitive + $actualResult | should be "00000000 01 02 03 04 .... " + } + + # This test is to validate that integers can be piped to the format-hex + # and properly represented as characters in the string + It "ValidateIntegerInputThatPresentAsCharacters" { + + $result = 65..68 | Format-Hex + $result | Should Not BeNullOrEmpty + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + # whitespace sensitive + $actualResult | should be "00000000 41 42 43 44 ABCD " + } + + # This test is to validate that integers can be piped to the format-hex + It "ValidateIntegerRawInput" { + + $result = 1,2,3,4 | Format-Hex -Raw + $result | Should Not BeNullOrEmpty + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + # whitespace sensitive + $actualResult | should be "00000000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ................" + } + + # handle int64 + It "ValidateInteger64" { + + $result = [int64]::MaxValue | Format-Hex + $result | Should Not BeNullOrEmpty + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() + # whitespace sensitive + $actualResult | Should Match "00000000 FF FF FF FF FF FF FF 7F ." + } + + # handle bytes, int16, int32, and int64 + It "Validate combined and reduced number formatting" { + $b = 65 # fits in a byte + $i16 = 32767 # fits in an int16 + $i32 = 2147483647 # an int32 + $i64 = 9223372036854775807 # an int64 + $result = $b,$i16,$i32,$i64 | format-Hex + $result.GetType().Name | should be 'ByteCollection' + $actualResult = $result.ToString() + $actualResult | should Match "00000000 41 FF 7F FF FF FF 7F FF FF FF FF FF FF FF 7F A" + } + + # handle bytes, int16, int32, and int64 + It "Validate combined and with raw number formatting" { + $b = 65 # fits in a byte + $i16 = 32767 # fits in an int16 + $i32 = 2147483647 # an int32 + $i64 = 9223372036854775807 # an int64 + # this will cause 2 lines to be emitted + $result = $b,$i16,$i32,$i64 | format-Hex -Raw + $result[0].GetType().Name | should be 'ByteCollection' + $result[1].GetType().Name | should be 'ByteCollection' + $result0 = $result[0].ToString() + $result0 | should match "00000000 41 00 00 00 FF 7F 00 00 FF FF FF 7F FF FF FF FF A" + $result1 = $result[1].ToString() + $result1 | should match "00000010 FF FF FF 7F .." + } + + # This test is to validate that streamed text does not have buffer underrun problems + It "ValidateEachBufferHasCorrectContentForStreamingText" { + $result = "a" * 30 | Format-Hex + $result | Should Not BeNullOrEmpty + $result.GetType().Name | Should Be 'ByteCollection' + $actualResult = $result.ToString() -split "`r`n" + $actualResult.Count | should be 2 + $actualResult[0].ToString() | Should be "00000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa" + $actualResult[1].ToString() | Should be "00000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaa " + } + + # This test is to validate that files do not have buffer underrun problems + It "ValidateEachBufferHasCorrectContentForFiles" { + $result = Format-Hex -path $InputFile2 + $result | Should Not BeNullOrEmpty + $result.Count | should be 2 + $result[0].ToString() | Should be "00000000 54 68 69 73 20 69 73 20 61 20 62 69 74 20 6D 6F This is a bit mo" + $result[1].ToString() | Should be "00000010 72 65 20 74 65 78 74 0D 0A re text.. " + } + + # This test ensures that if we stream bytes from a file, the output is correct + It "ValidateStreamOfBytesFromFileHasProperOutput" { + $result = Get-Content $InputFile -Encoding Byte | Format-Hex + $result | Should Not BeNullOrEmpty + $result.GetType().Name | Should Be "ByteCollection" + $result.ToString() | Should be "00000000 48 65 6C 6C 6F 20 57 6F 72 6C 64 0D 0A Hello World.. " + } + + # This test is to validate the alias for Format-Hex cmdlet. + It "ValidateCmdletAlias" { + + try + { + $result = Get-Command fhx -ErrorAction Stop + $result | Should Not BeNullOrEmpty + $result.CommandType.ToString() | Should Be "Alias" + } + catch + { + $_ | Should BeNullOrEmpty + } + } +} diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ImportExportCSV.Delimiter.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ImportExportCSV.Delimiter.Tests.ps1 new file mode 100644 index 0000000000..7c1a2f9741 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ImportExportCSV.Delimiter.Tests.ps1 @@ -0,0 +1,65 @@ +Describe "Using delimiters with Export-CSV and Import-CSV behave correctly" -tags P1 { + BeforeAll { + # note, we will not use "," as that's the default for CSV + $delimiters = "/", " ", "@", "#", "$", "\", "&", "(", ")", + "{", "}", "|", "<", ">", ";", "'", + '"', "~", "!", "%", "^", "*", "_", "+", ":", + "?", "-", "=", "[", "]", "." + $defaultDelimiter = [System.Globalization.CultureInfo]::CurrentCulture.TextInfo.ListSeparator + $d = get-date + $testCases = @( + foreach($del in $delimiters) + { + @{ Delimiter = $del; Data = $d; ExpectedResult = $d.Ticks } + } + ) + } + AfterEach { + [System.Globalization.CultureInfo]::CurrentCulture.TextInfo.ListSeparator = $defaultDelimiter + remove-item -force -ea silentlycontinue TESTDRIVE:/file.csv + } + + It "Disallow use of null delimiter" { + $d | export-csv TESTDRIVE:/file.csv + { import-csv -path TESTDRIVE:/file.csv -delimiter $null } | Should Throw "Delimiter" + } + + It "Disallow use of delimiter with useCulture parameter" { + $d | export-csv TESTDRIVE:/file.csv + { import-csv -path TESTDRIVE:/file.csv -useCulture "," } | Should Throw "','" + } + + It "Imports the same properties as exported" { + $a = [pscustomobject]@{ a = 1; b = 2; c = 3 } + $a | export-Csv TESTDRIVE:/file.csv + $b = import-csv TESTDRIVE:/file.csv + @($b.psobject.properties).count | should be 3 + $b.a | Should be $a.a + $b.b | Should be $a.b + $b.c | Should be $a.c + } + + # parameter generated tests + It 'Delimiter with CSV import will fail correctly when culture does not match' -testCases $testCases { + param ($delimiter, $Data, $ExpectedResult) + [System.Globalization.CultureInfo]::CurrentCulture.TextInfo.ListSeparator = $delimiter + $Data | export-CSV TESTDRIVE:\File.csv -useCulture + $i = Import-CSV TESTDRIVE:\File.csv + $i.Ticks | Should Not Be $ExpectedResult + } + + It 'Delimiter with CSV import will succeed when culture matches export' -testCases $testCases { + param ($delimiter, $Data, $ExpectedResult) + [System.Globalization.CultureInfo]::CurrentCulture.TextInfo.ListSeparator = $delimiter + $Data | export-CSV TESTDRIVE:\File.csv -useCulture + $i = Import-CSV TESTDRIVE:\File.csv -useCulture + $i.Ticks | Should Be $ExpectedResult + } + + It 'Delimiter with CSV import will succeed when delimiter is used explicitly' -testCases $testCases { + param ($delimiter, $Data, $ExpectedResult) + $Data | export-CSV TESTDRIVE:\File.csv -delimiter $delimiter + $i = Import-CSV TESTDRIVE:\File.csv -delimiter $delimiter + $i.Ticks | Should Be $ExpectedResult + } +} diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/MiscCmdletUpdates.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/MiscCmdletUpdates.Tests.ps1 new file mode 100644 index 0000000000..9e6138387b --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/MiscCmdletUpdates.Tests.ps1 @@ -0,0 +1,54 @@ +Describe "GetDateFormatUpdates" -tags 'P1', 'RI' { + + It "Verifies that FileDate format works" { + $date = Get-Date + $expectedFormat = "{0:yyyyMMdd}" -f $date + $actualFormat = Get-Date -Date $date -Format FileDate + + $actualFormat | Should be $expectedFormat + } + + It "Verifies that FileDateUniversal format works" { + $date = (Get-Date).ToUniversalTime() + $expectedFormat = "{0:yyyyMMddZ}" -f $date + $actualFormat = Get-Date -Date $date -Format FileDateUniversal + + $actualFormat | Should be $expectedFormat + } + + It "Verifies that FileDateTime format works" { + $date = Get-Date + $expectedFormat = "{0:yyyyMMddTHHmmssffff}" -f $date + $actualFormat = Get-Date -Date $date -Format FileDateTime + + $actualFormat | Should be $expectedFormat + } + + It "Verifies that FileDateTimeUniversal format works" { + $date = (Get-Date).ToUniversalTime() + $expectedFormat = "{0:yyyyMMddTHHmmssffffZ}" -f $date + $actualFormat = Get-Date -Date $date -Format FileDateTimeUniversal + + $actualFormat | Should be $expectedFormat + } + +} + +Describe "GetRandomMiscTests" -tags 'P1', 'RI' { + It "Shouldn't overflow when using max range" { + + $hadError = $false + + try + { + ## Don't actually need to validate + Get-Random -Minimum ([Int32]::MinValue) -Maximum ([Int32]::MaxValue) -ErrorAction Stop + } + catch + { + $hadError = $true + } + + $hadError | Should be $false + } +} \ No newline at end of file diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/NewGuid.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/NewGuid.Tests.ps1 new file mode 100644 index 0000000000..1a912a27b2 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/NewGuid.Tests.ps1 @@ -0,0 +1,19 @@ +Describe -Tags "Unit","DRT" "New-Guid" { + + It "returns a new guid" { + $guid = New-Guid + $guid.GetType().FullName | Should Be "System.Guid" + } + + It "should not be all zeros" { + $guid = New-Guid + $guid.ToString() | Should Not Be "00000000-0000-0000-0000-000000000000" + } + + It "should return different guids with each call" { + $guid1 = New-Guid + $guid2 = New-Guid + $guid1.ToString() | Should Not Be $guid2.ToString() + } +} + diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/NewTemporaryFile.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/NewTemporaryFile.Tests.ps1 new file mode 100644 index 0000000000..e705cb4a2a --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/NewTemporaryFile.Tests.ps1 @@ -0,0 +1,38 @@ +# This is a Pester test suite to validate the New-TemporaryFile cmdlet in the Microsoft.PowerShell.Utility module. +# +# Copyright (c) Microsoft Corporation, 2015 +# + +<# + Purpose: + Verify that New-TemporaryFile creates a temporary file. + + Action: + Run New-TemporaryFile. + + Expected Result: + A FileInfo object for the temporary file is returned. +#> + +Describe "NewTemporaryFile" -tags 'DRT' { + + It "creates a new temporary file" { + $tempFile = New-TemporaryFile + + Test-Path $tempFile | Should be $true + $tempFile.GetType().Name | Should be "FileInfo" + + if(Test-Path $tempFile) + { + Remove-Item $tempFile -ErrorAction SilentlyContinue -Force + } + } + + It "with WhatIf does not create a file" { + New-TemporaryFile -WhatIf | Should Be $null + } + + It "has an OutputType of System.IO.FileInfo" { + (Get-Command New-TemporaryFile).OutputType | Should Be "System.IO.FileInfo" + } +} diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Pester.Commands.Cmdlets.JsonTests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Pester.Commands.Cmdlets.JsonTests.ps1 new file mode 100644 index 0000000000..913ee65e32 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Pester.Commands.Cmdlets.JsonTests.ps1 @@ -0,0 +1,1465 @@ +# +# Copyright (c) Microsoft Corporation, 2015 +# +# This is a Pester test suite which validate the Json cmdlets. +# + +# +# This 'Describe' is for tests that were converted from utscripts (SDXROOT/admin/monad/tests/monad/DRT/utscripts) +# and C# tests (SDXROOT/admin/monad/tests/monad/DRT/commands/utility/UnitTests) to Pester. +# +Describe "Json Tests" -Tags "RI", "P1" { + + BeforeAll { + + function ValidateSampleObject + { + param ($result, [switch]$hasEmbeddedSampleObject ) + + Write-Verbose "validating deserialized SampleObject" -Verbose + $result.SampleInt | Should Be 98765 + $result.SampleString | Should Match "stringVal" + $result.SampleArray.Count | Should Be 2 + $result.SampleTrue | Should Be $true + $result.SampleFalse | Should Be $false + $result.SampleNull | Should Be $null + $result.SampleFloat | Should Be 9.8765E+43 + + if ($hasEmbeddedSampleObject) + { + Write-Verbose "validating deserialized Embedded SampleObject" -Verbose + ValidateSampleObject -result $result.SampleObject + } + } + + } + + Context "ConvertTo-Json Bug Fixes" { + + It "ConvertTo-JSON should not have hard coded english error message" { + + # Test follow-up for bug WinBlue: 163372 - ConvertTo-JSON has hard coded english error message. + $process = Get-Process -Id $PID + $hash = @{ $process = "def" } + $expectedFullyQualifiedErrorId = "NonStringKeyInDictionary,Microsoft.PowerShell.Commands.ConvertToJsonCommand" + + try + { + ConvertTo-Json -InputObject $hash + throw "CodeExecuted" + } + catch + { + $_.FullyQualifiedErrorId | should be $expectedFullyQualifiedErrorId + } + } + + It "ConvertTo-Json should handle terms with double quotes" { + + # Test follow-up for bug WinBlue: 11484 - ConvertTo-Json can't handle terms with double quotes. + + $notcompressed = ConvertTo-JSON @{ FirstName = 'Hello " World' } + $compressed = ConvertTo-Json @{ FirstName = 'Hello " World' } -Compress + $valueFromNotCompressedResult = ConvertFrom-Json -InputObject $notcompressed + $valueFromCompressedResult = ConvertFrom-Json -InputObject $compressed + + $valueFromNotCompressedResult.FirstName | Should Match $valueFromCompressedResult.FirstName + } + + It "Convertto-Json should handle Enum based on Int64" { + + # Test follow-up for bug Win8: 378368 Convertto-Json problems with Enum based on Int64. + $src = @" +namespace Bug378368 +{ + public enum TestEnum : ulong + { + One = 1, + Two = 2 + } + + public enum TestEnum1 : long + { + One = 1, + Two = 2 + } + + public enum TestEnum2 : int + { + One = 1, + Two = 2 + } + + public class Test + { + public TestEnum TestEnum + { + get { return testEnum; } + set { testEnum = value; } + } + + private TestEnum testEnum = TestEnum.One; + + public TestEnum1 TestEnum1 + { + get { return testEnum1; } + set { testEnum1 = value; } + } + + private TestEnum1 testEnum1 = TestEnum1.Two; + + public TestEnum2 TestEnum2 + { + get { return testEnum2; } + set { testEnum2 = value; } + } + + private TestEnum2 testEnum2 = TestEnum2.One; + } +} +"@ + Add-Type $src + $op = new-object Bug378368.Test | convertto-json | convertfrom-json + $op.TestEnum | Should Be "One" + $op.TestEnum1 | Should Be "Two" + $op.TestEnum2 | Should Be 1 + } + + It "Test followup for Windows 8 bug 121627" { + + $JsonString = Get-Command Get-help |Select-Object Name, Noun, Verb| ConvertTo-Json + $actual = ConvertFrom-Json $JsonString + + $actual.Name | Should Be "Get-Help" + $actual.Noun | Should Be "Help" + $actual.Verb | Should Be "Get" + } + } + + Context "ConvertFrom and ConvertTo on JsonObject Tests" { + + It "Convert dictionary to PSObject" { + + $response = ConvertFrom-Json '{"d":{"__type":"SimpleJsonObject","Name":{"First":"Joel","Last":"Wood"},"Greeting":"Hello"}}' + $response.d.Name.First | Should Match "Joel" + } + + It "Convert to Json using PSOjbect" { + + $response = ConvertFrom-Json '{"d":{"__type":"SimpleJsonObject","Name":{"First":"Joel","Last":"Wood"},"Greeting":"Hello"}}' + + $response2 = ConvertTo-Json -InputObject $response -ErrorAction Continue + $response2 = ConvertTo-Json -InputObject $response -ErrorAction Inquire + $response2 = ConvertTo-Json -InputObject $response -ErrorAction SilentlyContinue + $response2 = ConvertTo-Json -InputObject $response -Depth 2 -Compress + $response2 | Should Be '{"d":{"Name":{"First":"Joel","Last":"Wood"},"Greeting":"Hello"}}' + + $response2 = ConvertTo-Json -InputObject $response -Depth 1 -Compress + $nameString = [System.Management.Automation.LanguagePrimitives]::ConvertTo($response.d.Name, [string]) + $response2 | Should Be "{`"d`":{`"Name`":`"$nameString`",`"Greeting`":`"Hello`"}}" + + $result1 = @" +{ + "d": { + "Name": { + "First": "Joel", + "Last": "Wood" + }, + "Greeting": "Hello" + } +} +"@ + $response2 = ConvertTo-Json -InputObject $response -Depth 2 + $response2 | Should Match $result1 + + $result2 = @" +{ + "d": { + "Name": "$nameString", + "Greeting": "Hello" + } +} +"@ + $response2 = ConvertTo-Json -InputObject $response -Depth 1 + $response2 | Should Match $result2 + + $arraylist = new-Object System.Collections.ArrayList + [void]$arraylist.Add("one") + [void]$arraylist.Add("two") + [void]$arraylist.Add("three") + $response2 = ConvertTo-Json -InputObject $arraylist -Compress + $response2 | Should Be '["one","two","three"]' + + $result3 = @" +[ + "one", + "two", + "three" +] +"@ + $response2 = ConvertTo-Json -InputObject $arraylist + $response2 | Should Be $result3 + + $response2 = $arraylist | ConvertTo-Json + $response2 | Should Be $result3 + } + + It "Convert to Json using hashtable" { + + $nameHash = @{First="Joe1";Last="Wood"} + $dHash = @{Name=$nameHash; Greeting="Hello"} + $rootHash = @{d=$dHash} + $response3 = ConvertTo-Json -InputObject $rootHash -Depth 2 -Compress + $response3 | Should Be '{"d":{"Greeting":"Hello","Name":{"Last":"Wood","First":"Joe1"}}}' + + $response3 = ConvertTo-Json -InputObject $rootHash -Depth 1 -Compress + $response3 | Should Be '{"d":{"Greeting":"Hello","Name":"System.Collections.Hashtable"}}' + + $result4 = @" +{ + "d": { + "Greeting": "Hello", + "Name": { + "Last": "Wood", + "First": "Joe1" + } + } +} +"@ + $response3 = ConvertTo-Json -InputObject $rootHash -Depth 2 + $response3 | Should Be $result4 + + $result5 = @" +{ + "d": { + "Greeting": "Hello", + "Name": "System.Collections.Hashtable" + } +} +"@ + $response3 = ConvertTo-Json -InputObject $rootHash -Depth 1 + $response3 | Should Be $result5 + } + + It "Convert from Json allows an empty string" { + + $emptyStringResult = ConvertFrom-Json "" + $emptyStringResult | Should Be $null + } + } + + Context "JsonObject Tests" { + + It "AddMember on JsonObject" { + + # create a Version object + $versionObject = New-Object System.Version 2, 3, 4, 14 + + # add a NoteProperty member called Note with a text note + $versionObject | Add-Member -MemberType NoteProperty -Name Note -Value "a version object" + + # add an AliasProperty called Rev as an alias to the Revison property + $versionObject | Add-Member -MemberType AliasProperty -Name Rev -Value Revision + + # add a ScriptProperty called IsOld which returns whether the version is an older version + $versionObject | Add-Member -MemberType ScriptProperty -Name IsOld -Value { ($this.Major -le 3) } + + $jstr = ConvertTo-Json $versionObject + + # convert the JSON string to a JSON object + $json = ConvertFrom-Json $jstr + + # Check the basic properties + $json.Major | Should Be 2 + $json.Minor | Should Be 3 + $json.Build | Should Be 4 + $json.Revision | Should Be 14 + $json.Note | Should Match "a version object" + + # Check the AliasProperty + $json.Rev | Should Be $json.Revision + + # Check the ScriptProperty + $json.IsOld | Should Be $true + } + + It "ConvertFrom-Json with a key value pair" { + + $json = "{name:1}" + $result = ConvertFrom-Json $json + $result.name | Should Be 1 + } + + It "ConvertFrom-Json with a simple array" { + + $json = "[1,2,3,4,5,6]" + $result = ConvertFrom-Json $json + $result.Count | Should Be 6 + $result.GetType().BaseType.fullname | Should Be "System.Array" + } + + It "ConvertFrom-Json with a float value" { + + $json = '{"SampleFloat1":1.2345E67, "SampleFloat2":-7.6543E-12}' + $result = ConvertFrom-Json $json + + $sampleFloat1 = Invoke-Expression 1.2345E67 + $result.SampleFloat1 | Should Be $sampleFloat1 + + $sampleFloat2 = Invoke-Expression -7.6543E-12 + $result.SampleFloat2 | Should Be $sampleFloat2 + } + + It "ConvertFrom-Json hash table nested in array" { + + $json = "['one', 'two', {'First':1,'Second':2,'Third':['Five','Six', 'Seven']}, 'four']" + $result = ConvertFrom-Json $json + + $result.Count | Should Be 4 + $result[0] | Should Be "one" + $result[1] | Should Be "two" + $result[3] | Should Be "four" + + $hash = $result[2] + $hash.First | Should Be 1 + $hash.Second | Should Be 2 + $hash.Third.Count | Should Be 3 + $hash.Third[0] | Should Be "Five" + $hash.Third[1] | Should Be "Six" + $hash.Third[2] | Should Be "Seven" + } + + It "ConvertFrom-Json array nested in hash table" { + + $json = '{"First":["one", "two", "three"], "Second":["four", "five"], "Third": {"blah": 4}}' + $result = ConvertFrom-Json $json + + $result.First.Count | Should Be 3 + $result.First[0] | Should Be "one" + $result.First[1] | Should Be "two" + $result.First[2] | Should Be "three" + + $result.Second.Count | Should Be 2 + $result.Second[0] | Should Be "four" + $result.Second[1] | Should Be "five" + + $result.Third.blah | Should Be "4" + } + + It "ConvertFrom-Json case insensitive test" { + + $json = '{"sAMPleValUE":12345}' + $result = ConvertFrom-Json $json + + $result.SampleValue | Should Be 12345 + } + + + It "ConvertFrom-Json sample values" { + + $json = '{"SampleInt":98765, "SampleString":"stringVal","SampleArray":[2,"two"], "SampleTrue":true, "SampleFalse":false,"SampleNull":null, "SampleFloat":9.8765E43}' + $result = ConvertFrom-Json $json + + # Validate the result object + ValidateSampleObject -result $result + + + $json = '{"SampleInt":98765, "SampleString":"stringVal","SampleArray":[2,"two"], "SampleTrue":true, ' + + '"SampleFalse":false,"SampleNull":null, "SampleFloat":9.8765E43, "SampleObject":'+ + '{"SampleInt":98765, "SampleString":"stringVal","SampleArray":[2,"two"], '+ + '"SampleTrue":true, "SampleFalse":false,"SampleNull":null, "SampleFloat":9.8765E43}}' + + # Validate the result object + $result = ConvertFrom-Json $json + ValidateSampleObject -result $result -hasEmbeddedSampleObject + } + + It "ConvertFrom-Json with special characters" { + + $json = '{"SampleValue":"\"\\\b\f\n\r\t\u4321\uD7FF"}' + $result = ConvertFrom-Json $json + $result.SampleValue[0] | Should Be '"' + $result.SampleValue[1] | Should Be '\' + $result.SampleValue[2] | Should Be 0x8 + $result.SampleValue[3] | Should Be 0xC + $result.SampleValue[4] | Should Be 0xA + $result.SampleValue[5] | Should Be 0xD + $result.SampleValue[6] | Should Be 0x9 + $result.SampleValue[7] | Should Be 0x4321 + $result.SampleValue[8] | Should Be 0xD7FF + } + } +} + +# This Describe is for new Json tests +# +Describe "Validate Json serialization" -Tags "BVT" { + + Context "Validate Json serialization ascii values" { + + $testCases = @( + @{ + TestInput = 0 + ToJson = 'null' + FromJson = '' + } + @{ + TestInput = 1 + ToJson = '"\u0001"' + FromJson = '' + } + @{ + TestInput = 2 + ToJson = '"\u0002"' + FromJson = '' + } + @{ + TestInput = 3 + ToJson = '"\u0003"' + FromJson = '' + } + @{ + TestInput = 4 + ToJson = '"\u0004"' + FromJson = '' + } + @{ + TestInput = 5 + ToJson = '"\u0005"' + FromJson = '' + } + @{ + TestInput = 6 + ToJson = '"\u0006"' + FromJson = '' + } + @{ + TestInput = 7 + ToJson = '"\u0007"' + FromJson = '' + } + @{ + TestInput = 8 + ToJson = '"\b"' + FromJson = '' + } + @{ + TestInput = 9 + ToJson = '"\t"' + FromJson = ' ' + } + @{ + TestInput = 10 + ToJson = '"\n"' + FromJson = "`n" + } + @{ + TestInput = 11 + ToJson = '"\u000b"' + FromJson = ' ' + } + @{ + TestInput = 12 + ToJson = '"\f"' + FromJson = ' ' + } + @{ + TestInput = 13 + ToJson = '"\r"' + FromJson = '' + } + @{ + TestInput = 14 + ToJson = '"\u000e"' + FromJson = '' + } + @{ + TestInput = 15 + ToJson = '"\u000f"' + FromJson = '' + } + @{ + TestInput = 16 + ToJson = '"\u0010"' + FromJson = '' + } + @{ + TestInput = 17 + ToJson = '"\u0011"' + FromJson = '' + } + @{ + TestInput = 18 + ToJson = '"\u0012"' + FromJson = '' + } + @{ + TestInput = 19 + ToJson = '"\u0013"' + FromJson = '' + } + @{ + TestInput = 20 + ToJson = '"\u0014"' + FromJson = '' + } + @{ + TestInput = 21 + ToJson = '"\u0015"' + FromJson = '' + } + @{ + TestInput = 22 + ToJson = '"\u0016"' + FromJson = '' + } + @{ + TestInput = 23 + ToJson = '"\u0017"' + FromJson = '' + } + @{ + TestInput = 24 + ToJson = '"\u0018"' + FromJson = '' + } + @{ + TestInput = 25 + ToJson = '"\u0019"' + FromJson = '' + } + @{ + TestInput = 26 + ToJson = '"\u001a"' + FromJson = '' + } + @{ + TestInput = 27 + ToJson = '"\u001b"' + FromJson = '' + } + @{ + TestInput = 28 + ToJson = '"\u001c"' + FromJson = '' + } + @{ + TestInput = 29 + ToJson = '"\u001d"' + FromJson = '' + } + @{ + TestInput = 30 + ToJson = '"\u001e"' + FromJson = '' + } + @{ + TestInput = 31 + ToJson = '"\u001f"' + FromJson = '' + } + @{ + TestInput = 32 + ToJson = '" "' + FromJson = ' ' + } + @{ + TestInput = 33 + ToJson = '"!"' + FromJson = '!' + } + @{ + TestInput = 34 + ToJson = '"\""' + FromJson = '"' + } + @{ + TestInput = 35 + ToJson = '"#"' + FromJson = '#' + } + @{ + TestInput = 36 + ToJson = '"$"' + FromJson = '$' + } + @{ + TestInput = 37 + ToJson = '"%"' + FromJson = '%' + } + @{ + TestInput = 38 + ToJson = '"\u0026"' + FromJson = '&' + } + @{ + TestInput = 39 + ToJson = '"\u0027"' + FromJson = "'" + } + @{ + TestInput = 40 + ToJson = '"("' + FromJson = '(' + } + @{ + TestInput = 41 + ToJson = '")"' + FromJson = ')' + } + @{ + TestInput = 42 + ToJson = '"*"' + FromJson = '*' + } + @{ + TestInput = 43 + ToJson = '"+"' + FromJson = '+' + } + @{ + TestInput = 44 + ToJson = '","' + FromJson = ',' + } + @{ + TestInput = 45 + ToJson = '"-"' + FromJson = '-' + } + @{ + TestInput = 46 + ToJson = '"."' + FromJson = '.' + } + @{ + TestInput = 47 + ToJson = '"/"' + FromJson = '/' + } + @{ + TestInput = 48 + ToJson = '"0"' + FromJson = '0' + } + @{ + TestInput = 49 + ToJson = '"1"' + FromJson = '1' + } + @{ + TestInput = 50 + ToJson = '"2"' + FromJson = '2' + } + @{ + TestInput = 51 + ToJson = '"3"' + FromJson = '3' + } + @{ + TestInput = 52 + ToJson = '"4"' + FromJson = '4' + } + @{ + TestInput = 53 + ToJson = '"5"' + FromJson = '5' + } + @{ + TestInput = 54 + ToJson = '"6"' + FromJson = '6' + } + @{ + TestInput = 55 + ToJson = '"7"' + FromJson = '7' + } + @{ + TestInput = 56 + ToJson = '"8"' + FromJson = '8' + } + @{ + TestInput = 57 + ToJson = '"9"' + FromJson = '9' + } + @{ + TestInput = 58 + ToJson = '":"' + FromJson = ':' + } + @{ + TestInput = 59 + ToJson = '";"' + FromJson = ';' + } + @{ + TestInput = 60 + ToJson = '"\u003c"' + FromJson = '<' + } + @{ + TestInput = 61 + ToJson = '"="' + FromJson = '=' + } + @{ + TestInput = 62 + ToJson = '"\u003e"' + FromJson = '>' + } + @{ + TestInput = 63 + ToJson = '"?"' + FromJson = '?' + } + @{ + TestInput = 64 + ToJson = '"@"' + FromJson = '@' + } + @{ + TestInput = 65 + ToJson = '"A"' + FromJson = 'A' + } + @{ + TestInput = 66 + ToJson = '"B"' + FromJson = 'B' + } + @{ + TestInput = 67 + ToJson = '"C"' + FromJson = 'C' + } + @{ + TestInput = 68 + ToJson = '"D"' + FromJson = 'D' + } + @{ + TestInput = 69 + ToJson = '"E"' + FromJson = 'E' + } + @{ + TestInput = 70 + ToJson = '"F"' + FromJson = 'F' + } + @{ + TestInput = 71 + ToJson = '"G"' + FromJson = 'G' + } + @{ + TestInput = 72 + ToJson = '"H"' + FromJson = 'H' + } + @{ + TestInput = 73 + ToJson = '"I"' + FromJson = 'I' + } + @{ + TestInput = 74 + ToJson = '"J"' + FromJson = 'J' + } + @{ + TestInput = 75 + ToJson = '"K"' + FromJson = 'K' + } + @{ + TestInput = 76 + ToJson = '"L"' + FromJson = 'L' + } + @{ + TestInput = 77 + ToJson = '"M"' + FromJson = 'M' + } + @{ + TestInput = 78 + ToJson = '"N"' + FromJson = 'N' + } + @{ + TestInput = 79 + ToJson = '"O"' + FromJson = 'O' + } + @{ + TestInput = 80 + ToJson = '"P"' + FromJson = 'P' + } + @{ + TestInput = 81 + ToJson = '"Q"' + FromJson = 'Q' + } + @{ + TestInput = 82 + ToJson = '"R"' + FromJson = 'R' + } + @{ + TestInput = 83 + ToJson = '"S"' + FromJson = 'S' + } + @{ + TestInput = 84 + ToJson = '"T"' + FromJson = 'T' + } + @{ + TestInput = 85 + ToJson = '"U"' + FromJson = 'U' + } + @{ + TestInput = 86 + ToJson = '"V"' + FromJson = 'V' + } + @{ + TestInput = 87 + ToJson = '"W"' + FromJson = 'W' + } + @{ + TestInput = 88 + ToJson = '"X"' + FromJson = 'X' + } + @{ + TestInput = 89 + ToJson = '"Y"' + FromJson = 'Y' + } + @{ + TestInput = 90 + ToJson = '"Z"' + FromJson = 'Z' + } + @{ + TestInput = 91 + ToJson = '"["' + FromJson = '[' + } + @{ + TestInput = 92 + ToJson = '"\\"' + FromJson = '\' + } + @{ + TestInput = 93 + ToJson = '"]"' + FromJson = ']' + } + @{ + TestInput = 94 + ToJson = '"^"' + FromJson = '^' + } + @{ + TestInput = 95 + ToJson = '"_"' + FromJson = '_' + } + @{ + TestInput = 96 + ToJson = '"`"' + FromJson = '`' + } + @{ + TestInput = 97 + ToJson = '"a"' + FromJson = 'a' + } + @{ + TestInput = 98 + ToJson = '"b"' + FromJson = 'b' + } + @{ + TestInput = 99 + ToJson = '"c"' + FromJson = 'c' + } + @{ + TestInput = 100 + ToJson = '"d"' + FromJson = 'd' + } + @{ + TestInput = 101 + ToJson = '"e"' + FromJson = 'e' + } + @{ + TestInput = 102 + ToJson = '"f"' + FromJson = 'f' + } + @{ + TestInput = 103 + ToJson = '"g"' + FromJson = 'g' + } + @{ + TestInput = 104 + ToJson = '"h"' + FromJson = 'h' + } + @{ + TestInput = 105 + ToJson = '"i"' + FromJson = 'i' + } + @{ + TestInput = 106 + ToJson = '"j"' + FromJson = 'j' + } + @{ + TestInput = 107 + ToJson = '"k"' + FromJson = 'k' + } + @{ + TestInput = 108 + ToJson = '"l"' + FromJson = 'l' + } + @{ + TestInput = 109 + ToJson = '"m"' + FromJson = 'm' + } + @{ + TestInput = 110 + ToJson = '"n"' + FromJson = 'n' + } + @{ + TestInput = 111 + ToJson = '"o"' + FromJson = 'o' + } + @{ + TestInput = 112 + ToJson = '"p"' + FromJson = 'p' + } + @{ + TestInput = 113 + ToJson = '"q"' + FromJson = 'q' + } + @{ + TestInput = 114 + ToJson = '"r"' + FromJson = 'r' + } + @{ + TestInput = 115 + ToJson = '"s"' + FromJson = 's' + } + @{ + TestInput = 116 + ToJson = '"t"' + FromJson = 't' + } + @{ + TestInput = 117 + ToJson = '"u"' + FromJson = 'u' + } + @{ + TestInput = 118 + ToJson = '"v"' + FromJson = 'v' + } + @{ + TestInput = 119 + ToJson = '"w"' + FromJson = 'w' + } + @{ + TestInput = 120 + ToJson = '"x"' + FromJson = 'x' + } + @{ + TestInput = 121 + ToJson = '"y"' + FromJson = 'y' + } + @{ + TestInput = 122 + ToJson = '"z"' + FromJson = 'z' + } + @{ + TestInput = 123 + ToJson = '"{"' + FromJson = '{' + } + @{ + TestInput = 124 + ToJson = '"|"' + FromJson = '|' + } + @{ + TestInput = 125 + ToJson = '"}"' + FromJson = '}' + } + @{ + TestInput = 126 + ToJson = '"~"' + FromJson = '~' + } + @{ + TestInput = 127 + ToJson = '""' + FromJson = '' + } + ) + + function ValidateJsonSerializationForAsciiValues + { + param ($testCase) + + It "Validate 'ConvertTo-Json ([char]$($testCase.TestInput))', and 'ConvertTo-Json ([char]$($testCase.TestInput)) | ConvertFrom-Json'" { + + $result = @{ + ToJson = ConvertTo-Json ([char]$testCase.TestInput) + FromJson = ConvertTo-Json ([char]$testCase.TestInput) | ConvertFrom-Json + } + + if ($testCase.FromJson) + { + $result.FromJson | Should Be $testCase.FromJson + } + else + { + # There are two char for which the deserialized object must be compare to the serialized one via "Should Match" + # These values are [char]0 and [char]13. + $result.FromJson | Should Match $testCase.FromJson + } + $result.ToJson | Should Be $testCase.ToJson + } + } + + foreach ($testCase in $testCases) + { + ValidateJsonSerializationForAsciiValues $testCase + } + } + + Context "Validate Json serialization for types" { + + $testCases = @( + + ## Decimal types - Decimals are a 128-bit data type + @{ + TestInput = '[decimal]::MinValue' + FromJson = [decimal]::MinValue + ToJson = [decimal]::MinValue + } + @{ + TestInput = '[decimal]::MaxValue' + FromJson = [decimal]::MaxValue + ToJson = [decimal]::MaxValue + } + + # An sbyte is a signed 8-bit integer, and it ranges from -128 to 127. + # A byte is an unsigned 8-bit integer that ranges from 0 to 255 + @{ + TestInput = '[byte]::MinValue' + FromJson = [byte]::MinValue + ToJson = [byte]::MinValue + } + @{ + TestInput = '[byte]::MaxValue' + FromJson = [byte]::MaxValue + ToJson = [byte]::MaxValue + } + @{ + TestInput = '[sbyte]::MinValue' + FromJson = [sbyte]::MinValue + ToJson = [sbyte]::MinValue + } + @{ + TestInput = '[sbyte]::MaxValue' + FromJson = [sbyte]::MaxValue + ToJson = [sbyte]::MaxValue + } + @{ + TestInput = '[char]::MinValue' + FromJson = $null + ToJson = 'null' + } + @{ + TestInput = '[char]::MaxValue - 1' + FromJson = [char]::MaxValue - 1 + ToJson = [char]::MaxValue - 1 + } + @{ + TestInput = '[string]::Empty' + FromJson = [string]::Empty + ToJson = '""' + } + @{ + TestInput = '[string]"hello"' + FromJson = [string]"hello" + ToJson = '"hello"' + } + + # Int, int32, uint32, uint16, int16 + + # 32-bit signed integer + @{ + TestInput = '[int]::MaxValue' + FromJson = [int]::MaxValue + ToJson = [int]::MaxValue + } + @{ + TestInput = '[int]::MinValue' + FromJson = [int]::MinValue + ToJson = [int]::MinValue + } + @{ + TestInput = '[int32]::MaxValue' + FromJson = [int32]::MaxValue + ToJson = [int32]::MaxValue + } + @{ + TestInput = '[int32]::MinValue' + FromJson = [int32]::MinValue + ToJson = [int32]::MinValue + } + + # 32-bit unsigned integer + @{ + TestInput = '[uint32]::MaxValue' + FromJson = [uint32]::MaxValue + ToJson = [uint32]::MaxValue + } + @{ + TestInput = '[uint32]::MinValue' + FromJson = [uint32]::MinValue + ToJson = [uint32]::MinValue + } + + # 16-bit unsigned integer + @{ + TestInput = '[int16]::MinValue' + FromJson = [int16]::MinValue + ToJson = [int16]::MinValue + } + @{ + TestInput = '[uint16]::MaxValue' + FromJson = [uint16]::MaxValue + ToJson = [uint16]::MaxValue + } + + # 64-bit unsigned integer + @{ + TestInput = '[uint64]::MinValue' + FromJson = [uint64]::MinValue + ToJson = [uint64]::MinValue + } + @{ + TestInput = '[uint64]::MinValue' + FromJson = [uint64]::MinValue + ToJson = [uint64]::MinValue + } + + # 64 bit signed integer + @{ + TestInput = '[int64]::MaxValue' + FromJson = [int64]::MaxValue + ToJson = [int64]::MaxValue + } + @{ + TestInput = '[int64]::MinValue' + FromJson = [int64]::MinValue + ToJson = [int64]::MinValue + } + @{ + TestInput = '[long]::MaxValue' + FromJson = [long]::MaxValue + ToJson = [long]::MaxValue + } + @{ + TestInput = '[long]::MinValue' + FromJson = [long]::MinValue + ToJson = [long]::MinValue + } + + # Bool + @{ + TestInput = '[bool](1)' + FromJson = [bool](1) + ToJson = $true + } + @{ + TestInput = '[bool](0)' + FromJson = $false + ToJson = 'False' + } + + # Decimal + @{ + TestInput = '[decimal]::MaxValue' + FromJson = [decimal]::MaxValue + ToJson = [decimal]::MaxValue + } + @{ + TestInput = '[decimal]::MinValue' + FromJson = [decimal]::MinValue + ToJson = [decimal]::MinValue + } + + # Single + @{ + TestInput = '[single]::MaxValue' + FromJson = "3.40282347E+38" + ToJson = "3.40282347E+38" + } + @{ + TestInput = '[single]::MinValue' + FromJson = "-3.40282347E+38" + ToJson = "-3.40282347E+38" + } + + # Double + @{ + TestInput = '[double]::MaxValue' + FromJson = [double]::MaxValue + ToJson = [double]::MaxValue + } + @{ + TestInput = '[double]::MinValue' + FromJson = [double]::MinValue + ToJson = [double]::MinValue + } + ) + + function ValidateJsonSerialization + { + param ($testCase) + + It "Validate '$($testCase.TestInput) | ConvertTo-Json' and '$($testCase.TestInput) | ConvertTo-Json | ConvertFrom-Json'" { + + # The test case input is executed via invoke-expression. Then, we use this value as an input to ConvertTo-Json, + # and the result is saved into in the $result.ToJson variable. Lastly, this value is deserialized back using + # ConvertFrom-Json, and the value is saved to $result.FromJson for comparison. + + $expression = Invoke-Expression $testCase.TestInput + $result = @{ + ToJson = $expression | ConvertTo-Json + FromJson = $expression | ConvertTo-Json | ConvertFrom-Json + } + + $result.ToJson | Should Be $testCase.ToJson + $result.FromJson | Should Be $testCase.FromJson + } + } + + foreach ($testCase in $testCases) + { + ValidateJsonSerialization $testCase + } + } + + + Context "Validate Json Serialization for 'Get-CimClass' and 'Get-Command'" { + + function ValidateProperties + { + param ( + $serialized, + $expected, + $properties + ) + + # Validate that the two collections are the same size. + $expected.Count | Should Be $serialized.Count + + for ($index = 0; $index -lt $serialized.Count; $index++) + { + $serializedObject = $serialized[$index] + $expectedObject = $expected[$index] + foreach ($property in $properties) + { + # Write-Verbose "Validating $property" -Verbose + if ($property -eq "Qualifiers") + { + $serializedObject.$property.Count | Should Be $expectedObject.$property.Count + } + else + { + $serializedObject.$property | Should Be $expectedObject.$property + } + } + } + } + + It "Validate that CimClass Properties for win32_bios can be serialized using ConvertTo-Json and ConvertFrom-Json" { + + $class = Get-CimClass win32_bios + + $result = @{ + Expected = $class.CimClassProperties | ForEach-Object {$_} + SerializedViaJson = $class.CimClassProperties | ConvertTo-Json -Depth 10 | ConvertFrom-Json + } + + $propertiesToValidate = @("Name", "Flags", "Qualifiers", "ReferenceClassName") + + ValidateProperties -serialized $result.SerializedViaJson -expected $result.Expected -properties $propertiesToValidate + } + + It "Validate 'Get-Command Get-help' output with Json conversion" { + + $result = @{ + Expected = @(Get-Command Get-help) + SerializedViaJson = @(Get-Command Get-help | ConvertTo-Json | ConvertFrom-Json) + } + + $propertiesToValidate = @("Name", "Noun", "Verb") + ValidateProperties -serialized $result.SerializedViaJson -expected $result.Expected -properties $propertiesToValidate + } + + It "Validate 'Get-Command Get-Help, Get-command, Get-Member' output with Json conversion" { + + $result = @{ + Expected = @(Get-Command Get-Help, Get-Command, Get-Member) + SerializedViaJson = @(Get-Command Get-Help, Get-Command, Get-Member) | ConvertTo-Json | ConvertFrom-Json + } + + $propertiesToValidate = @("Name", "Source", "HelpFile") + ValidateProperties -serialized $result.SerializedViaJson -expected $result.Expected -properties $propertiesToValidate + } + + It "ConvertTo-JSON a dictionary of arrays" { + $a = 1..5 + $b = 6..10 + + $actual = @{'a'=$a;'b'=$b} | ConvertTo-Json + $expected = @' +{ + "a": [ + 1, + 2, + 3, + 4, + 5 + ], + "b": [ + 6, + 7, + 8, + 9, + 10 + ] +} +'@ + $actual | Should Be $expected + } + } +} + +Describe "Json Bug fixes" -Tags "RI", "P1" { + + function RunJsonTest + { + param ($testCase) + + It "$($testCase.Name)" { + + # Create a nested object + $start = 1 + $previous = @{ + Depth = $($testCase.NumberOfElements) + Next = $null + } + + ($($testCase.NumberOfElements)-1)..$start | foreach { + $current = @{ + Depth = $_ + Next = $previous + } + $previous = $current + } + + if ($testCase.ShouldThrow) + { + try + { + $previous | ConvertTo-Json -Depth $testCase.MaxDepth + throw "CodeExecuted" + } + catch + { + $_.FullyQualifiedErrorId | Should Be $testCase.FullyQualifiedErrorId + } + } + else + { + $theError = $null + try + { + $previous | ConvertTo-Json -Depth $testCase.MaxDepth | ConvertFrom-Json + } + catch + { + $theError = $_ + } + $theError | Should Be $null + } + } + } + + $testCases = @( + @{ + Name = "ConvertTo-Json -Depth 101 throws MaximumAllowedDepthReached when the user specifies a depth greather than 100." + NumberOfElements = 10 + MaxDepth = 101 + FullyQualifiedErrorId = "ReachedMaximumDepthAllowed,Microsoft.PowerShell.Commands.ConvertToJsonCommand" + ShouldThrow = $true + } + @{ + Name = "ConvertTo-Json and ConvertFrom-Json work for any depth less than or equal to 100." + NumberOfElements = 100 + MaxDepth = 100 + ShouldThrow = $false + } + @{ + Name = "ConvertTo-Json and ConvertFrom-Json work for depth 100 with an object larger than 100." + NumberOfElements = 105 + MaxDepth = 100 + ShouldThrow = $false + } + ) + + foreach ($testCase in $testCases) + { + RunJsonTest $testCase + } +} \ No newline at end of file diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 new file mode 100644 index 0000000000..0d0deff9a9 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 @@ -0,0 +1,86 @@ +Describe "Tests for the Import-PowerShellDataFile cmdlet" -Tags 'P1', 'RI' { + + It "Validates error on a missing path" { + + $foundError = "" + try + { + Import-PowerShellDataFile -Path c:\SomeMissingDirectory -ErrorAction Stop + } + catch + { + $foundError = $_.FullyQualifiedErrorId + } + + $foundError | Should be "PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand" + } + + It "Validates error on a directory" { + + $foundError = "" + try + { + Import-PowerShellDataFile ($env:SYSTEMDRIVE + '\') -ErrorAction Stop + } + catch + { + $foundError = $_.FullyQualifiedErrorId + } + + $foundError | Should be "CouldNotParseAsPowerShellDataFile,Import-PowerShellDataFile" + } + + It "Generates a good error on an insecure file" { + + $path = New-TemporaryFile + Set-Content $path '@{ Foo = Get-Process }' + + $foundError = "" + try + { + Import-PowerShellDataFile $path -ErrorAction Stop + } + catch + { + $foundError = $_.FullyQualifiedErrorId + } + finally + { + Remove-Item $path + } + + $foundError | Should be "InvalidOperationException,Import-PowerShellDataFile" + } + + It "Generates a good error on a file that isn't a PowerShell Data File (missing the hashtable root)" { + + $path = New-TemporaryFile + Set-Content $path '"Hello World"' + + $foundError = "" + try + { + Import-PowerShellDataFile $path -ErrorAction Stop + } + catch + { + $foundError = $_.FullyQualifiedErrorId + } + finally + { + Remove-Item $path + } + + $foundError | Should be "CouldNotParseAsPowerShellDataFileNoHashtableRoot,Import-PowerShellDataFile" + } + + It "Can parse a PowerShell Data File (detailed tests are in AST.SafeGetValue tests)" { + + $path = New-TemporaryFile + Set-Content $path '@{ "Hello" = "World" }' + + $result = Import-PowerShellDataFile $path -ErrorAction Stop + $result.Hello | Should be "World" + } + +} \ No newline at end of file diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/alias.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/alias.tests.ps1 new file mode 100644 index 0000000000..8e1e940119 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/alias.tests.ps1 @@ -0,0 +1,160 @@ +Describe "Alias tests" -Tags "innerloop", "P1", "RI" { + + BeforeAll { + $testPath = Join-Path testdrive:\ ("testAlias\[.test") + New-Item -ItemType Directory -Path $testPath -Force | Out-Null + + class TestData + { + [string] $testName + [string] $testFile + [string] $expectedError + + TestData($name, $file, $error) + { + $this.testName = $name + $this.testFile = $file + $this.expectedError = $error + } + } + } + + Context "Export-Alias literal path" { + BeforeAll { + $csvFile = Join-Path $testPath "alias.csv" + $ps1File = Join-Path $testPath "alias.ps1" + + $testCases = @() + $testCases += [TestData]::new("CSV", $csvFile, [NullString]::Value) + $testCases += [TestData]::new("PS1", $ps1File, [NullString]::Value) + $testCases += [TestData]::new("Empty string", "", "ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.ExportAliasCommand") + $testCases += [TestData]::new("Null", [NullString]::Value, "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ExportAliasCommand") + $testCases += [TestData]::new("Non filesystem provider", 'cert:\alias.ps1', "ReadWriteFileNotFileSystemProvider,Microsoft.PowerShell.Commands.ExportAliasCommand") + } + + $testCases | % { + + It "for $($_.testName)" { + + $test = $_ + try + { + Export-Alias -LiteralPath $test.testFile -ErrorAction SilentlyContinue + } + catch + { + $exportAliasError = $_ + } + + if($test.expectedError -eq $null) + { + Test-Path -LiteralPath $test.testFile | Should Be $true + } + else + { + $exportAliasError.FullyqualifiedErrorId | Should Be $test.expectedError + } + } + + AfterEach { + Remove-Item -LiteralPath $test.testFile -Force -ErrorAction SilentlyContinue + } + } + + It "when file exists with NoClobber" { + Export-Alias -LiteralPath $csvFile + + try + { + Export-Alias -LiteralPath $csvFile -NoClobber + } + catch + { + $exportAliasError = $_ + } + + $exportAliasError.FullyQualifiedErrorId | Should Be "NoClobber,Microsoft.PowerShell.Commands.ExportAliasCommand" + } + } + + Context "Export-All inside a literal path" { + BeforeEach { + Push-Location -LiteralPath $testPath + } + + It "with a CSV file" { + Export-Alias "alias.csv" + Test-Path -LiteralPath (Join-Path $testPath "alias.csv") | Should Be $true + } + + It "with NoClobber" { + $path = Export-Alias alias.csv + + try + { + Export-Alias alias.csv -NoClobber + } + catch + { + $exportAliasError = $_ + } + + $exportAliasError.FullyQualifiedErrorId | Should Be "NoClobber,Microsoft.PowerShell.Commands.ExportAliasCommand" + } + + AfterEach { + Pop-Location + } + } + + Context "Import-Alias literal path" { + + BeforeAll { + $csvFile = Join-Path $testPath "alias.csv" + $ps1File = Join-Path $testPath "alias.ps1" + + $testCases = @() + $testCases += [TestData]::new("Empty string", "", "ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.ImportAliasCommand") + $testCases += [TestData]::new("Null", [NullString]::Value, "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ImportAliasCommand") + $testCases += [TestData]::new("Non filesystem provider", 'cert:\alias.ps1', "NotSupported,Microsoft.PowerShell.Commands.ImportAliasCommand") + } + + $testCases | % { + + It "for $($_.testName)" { + $test = $_ + + try + { + Import-Alias -LiteralPath $test.testFile -ErrorAction SilentlyContinue + } + catch + { + $exportAliasError = $_ + } + + $exportAliasError.FullyqualifiedErrorId | Should Be $test.expectedError + } + } + + It "can be done from a CSV file" { + + # alias file definition content + $aliasDefinition = @' + "myuh","update-help","","ReadOnly, AllScope" +'@ + + $aliasFile = Join-Path $testPath "alias.csv" + $aliasDefinition | Out-File -LiteralPath $aliasFile + + Import-Alias -LiteralPath $aliasFile + + # Verify that the alias was imported + $definedAlias = Get-Alias myuh + + $definedAlias | Should Not Be $null + $definedAlias.Name | Should Be "myuh" + $definedAlias.Definition | Should Be "update-help" + } + } +} \ No newline at end of file diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/clixml.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/clixml.tests.ps1 new file mode 100644 index 0000000000..957df51177 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/clixml.tests.ps1 @@ -0,0 +1,187 @@ +Describe "CliXml test" -Tags "innerloop", "P1", "RI" { + + BeforeAll { + $testFilePath = Join-Path "testdrive:\" "testCliXml" + $subFilePath = Join-Path $testFilePath ".test" + + if(test-path $testFilePath) + { + Remove-Item $testFilePath -Force -Recurse + } + + # Create the test File and push the location into specified path + New-Item -Path $testFilePath -ItemType Directory | Out-Null + New-Item -Path $subFilePath -ItemType Directory | Out-Null + Push-Location $testFilePath + + class TestData + { + [string] $testName + [object] $inputObject + [string] $expectedError + [string] $testFile + + TestData($name, $file, $inputObj, $error) + { + $this.testName = $name + $this.inputObject = $inputObj + $this.expectedError = $error + $this.testFile = $file + } + } + } + + AfterAll { + Pop-Location + } + + Context "Export-CliXml" { + BeforeAll { + $gpsList = Get-Process powershell + $gps = $gpsList | Select-Object -First 1 + $filePath = Join-Path $subFilePath 'gps.xml' + + $testData = @() + $testData += [TestData]::new("with path as Null", [NullString]::Value, $gps, "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ExportClixmlCommand") + $testData += [TestData]::new("with path as Empty string", "", $gps, "ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.ExportClixmlCommand") + $testData += [TestData]::new("with path as non filesystem provider", "cert:\", $gps, "ReadWriteFileNotFileSystemProvider,Microsoft.PowerShell.Commands.ExportClixmlCommand") + } + + AfterEach { + Remove-Item $filePath -Force -ErrorAction SilentlyContinue + } + + $testData | % { + + It "$($_.testName)" { + $test = $_ + + try + { + Export-Clixml -LiteralPath $test.testFile -InputObject $test.inputObject -Force + } + catch + { + $exportCliXmlError = $_ + } + + $exportCliXmlError.FullyQualifiedErrorId | Should Be $test.expectedError + } + } + + It "can be created with literal path" { + + $filePath = Join-Path $subFilePath 'gps.xml' + Export-Clixml -LiteralPath $filePath -InputObject ($gpsList | Select-Object -First 1) + + $filePath | Should Exist + + $fileContent = Get-Content $filePath + $isExisted = $false + + foreach($item in $fileContent) + { + foreach($gpsItem in $gpsList) + { + $checkId = $gpsItem.Id + if (($null -ne $(Select-String -InputObject $item -SimpleMatch $checkId)) -and ($null -ne $(Select-String -InputObject $item -SimpleMatch "Id"))) + { + $isExisted = $true + break; + } + } + } + + $isExisted | Should Be $true + } + + It "can be created with literal path using pipeline" { + + + $filePath = Join-Path $subFilePath 'gps.xml' + ($gpsList | Select-Object -First 1) | Export-Clixml -LiteralPath $filePath + + $filePath | Should Exist + + $fileContent = Get-Content $filePath + $isExisted = $false + + foreach($item in $fileContent) + { + foreach($gpsItem in $gpsList) + { + $checkId = $gpsItem.Id + if (($null -ne $(Select-String -InputObject $item -SimpleMatch $checkId)) -and ($null -ne $(Select-String -InputObject $item -SimpleMatch "Id"))) + { + $isExisted = $true + break; + } + } + } + + $isExisted | Should Be $true + } + } + + Context "Import-CliXML" { + BeforeAll { + $gpsList = Get-Process powershell + $gps = $gpsList | Select-Object -First 1 + $filePath = Join-Path $subFilePath 'gps.xml' + + $testData = @() + $testData += [TestData]::new("with path as Null", [NullString]::Value, $null, "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ImportClixmlCommand") + $testData += [TestData]::new("with path as Empty string", "", $null, "ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.ImportClixmlCommand") + $testData += [TestData]::new("with path as non filesystem provider", "cert:\", $null, "ReadWriteFileNotFileSystemProvider,Microsoft.PowerShell.Commands.ImportClixmlCommand") + } + + $testData | % { + + It "$($_.testName)" { + $test = $_ + + try + { + Import-Clixml -LiteralPath $test.testFile + } + catch + { + $importCliXmlError = $_ + } + + $importCliXmlError.FullyQualifiedErrorId | Should Be $test.expectedError + } + } + + It "can import from a literal path" { + Export-Clixml -LiteralPath $filePath -InputObject $gps + $filePath | Should Exist + + $fileContent = Get-Content $filePath + $fileContent | Should Not Be $null + + $importedProcess = Import-Clixml $filePath + $gps.ProcessName | Should Be $importedProcess.ProcessName + $gps.Id | Should Be $importedProcess.Id + } + + It "can import from a literal path using pipeline" { + $gps | Export-Clixml -LiteralPath $filePath + $filePath | Should Exist + + $fileContent = Get-Content $filePath + $fileContent | Should Not Be $null + + $importedProcess = Import-Clixml $filePath + $gps.ProcessName | Should Be $importedProcess.ProcessName + $gps.Id | Should Be $importedProcess.Id + } + + It "test follow-up for WinBlue: 161470 - Export-CliXml errors in WhatIf scenarios" { + + $testPath = "testdrive:\Bug161470NonExistPath.txt" + Export-Clixml -Path $testPath -InputObject "string" -WhatIf + $testPath | Should Not Exist + } + } +} \ No newline at end of file diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/command.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/command.tests.ps1 new file mode 100644 index 0000000000..5480603b5b --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/command.tests.ps1 @@ -0,0 +1,80 @@ +Describe "Trace-Command" -tags "P1", "RI" { + + Context "Listner options" { + BeforeAll { + $logFile = New-Item "TestDrive:\traceCommandLog.txt" -Force + $actualLogFile = New-Item "TestDrive:\actualTraceCommandLog.txt" -Force + } + + AfterEach { + Remove-Item "TestDrive:\traceCommandLog.txt" -Force -ErrorAction SilentlyContinue + Remove-Item "TestDrive:\actualTraceCommandLog.txt" -Force -ErrorAction SilentlyContinue + } + + It "LogicalOperationStack works" { + $keyword = "Trace_Command_ListenerOption_LogicalOperationStack_Foo" + $stack = [System.Diagnostics.Trace]::CorrelationManager.LogicalOperationStack + $stack.Push($keyword) + + Trace-Command -Name * -Expression {echo Foo} -ListenerOption LogicalOperationStack -FilePath $logfile + + $log = Get-Content $logfile | Where-Object {$_ -like "*LogicalOperationStack=$keyword*"} + $log.Count | Should BeGreaterThan 0 + } + + It "Callstack works" { + Trace-Command -Name * -Expression {echo Foo} -ListenerOption Callstack -FilePath $logfile + $log = Get-Content $logfile | Where-Object {$_ -like "*Callstack= * System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)*"} + $log.Count | Should BeGreaterThan 0 + } + + It "Datetime works" { + $expectedDate = Trace-Command -Name * -Expression {Get-Date} -ListenerOption DateTime -FilePath $logfile + $log = Get-Content $logfile | Where-Object {$_ -like "*DateTime=*"} + $results = $log | ForEach-Object {[DateTime]::Parse($_.Split("=")[1])} + + ## allow a gap of 6 seconds. All traces should be finished within 6 seconds. + $allowedGap = [timespan](60 * 1000 * 1000) + $results | ForEach-Object { + $actualGap = $_ - $expectedDate; + if ($expectedDate -gt $_) + { + $actualGap = $expectedDate - $_; + } + + $allowedGap | Should BeGreaterThan $actualGap + } + } + + It "None options has no effect" { + Trace-Command -Name * -Expression {echo Foo} -ListenerOption None -FilePath $actualLogfile + Trace-Command -name * -Expression {echo Foo} -FilePath $logfile + + Compare-Object (Get-Content $actualLogfile) (Get-Content $logfile) | Should BeNullOrEmpty + } + + It "ThreadID works" { + Trace-Command -Name * -Expression {echo Foo} -ListenerOption ThreadId -FilePath $logfile + $log = Get-Content $logfile | Where-Object {$_ -like "*ThreadID=*"} + $results = $log | ForEach-Object {$_.Split("=")[1]} + + $results | % { $_ | Should Be ([threading.thread]::CurrentThread.ManagedThreadId) } + } + + It "Timestamp creates logs in ascending order" { + Trace-Command -Name * -Expression {echo Foo} -ListenerOption Timestamp -FilePath $logfile + $log = Get-Content $logfile | Where-Object {$_ -like "*Timestamp=*"} + $results = $log | ForEach-Object {$_.Split("=")[1]} + $sortedResults = $results | Sort-Object + $sortedResults | Should Be $results + } + + It "ProcessId logs current process Id" { + Trace-Command -Name * -Expression {echo Foo} -ListenerOption ProcessId -FilePath $logfile + $log = Get-Content $logfile | Where-Object {$_ -like "*ProcessID=*"} + $results = $log | ForEach-Object {$_.Split("=")[1]} + + $results | ForEach-Object { $_ | Should Be $pid } + } + } +} \ No newline at end of file diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/formatdata.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/formatdata.tests.ps1 new file mode 100644 index 0000000000..02d54a42f3 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/formatdata.tests.ps1 @@ -0,0 +1,64 @@ +Describe "FormatData" -tags "P1", "RI" { + + Context "Export" { + It "can export all types" { + try + { + $expectAllFormat = Get-FormatData -typename * + $expectAllFormat | Export-FormatData -path $env:temp\allformat.ps1xml -IncludeScriptBlock + + $sessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() + $sessionState.Formats.Clear() + $sessionState.Types.Clear() + + $runspace = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace($sessionState) + $runspace.Open() + + $runspace.CreatePipeline("Update-FormatData -AppendPath $env:temp\allformat.ps1xml").Invoke() + $actualAllFormat = $runspace.CreatePipeline("Get-FormatData -TypeName *").Invoke() + + $expectAllFormat.Count | Should Be $actualAllFormat.Count + Compare-Object $expectAllFormat $actualAllFormat | Should Be $null + $runspace.Close() + } + finally + { + Remove-Item -Path $env:temp\allformat.ps1xml -Force -ErrorAction SilentlyContinue + } + } + + It "works with literal path" { + $filename = 'TestDrive:\[formats.ps1xml' + Get-FormatData -TypeName * | Export-FormatData -LiteralPath $filename + (Test-Path -LiteralPath $filename) | Should Be $true + } + + It "should overwrite the destination file" { + $filename = 'TestDrive:\ExportFormatDataWithForce.ps1xml' + $unexpected = "SHOULD BE OVERWRITTEN" + $unexpected | Out-File -FilePath $filename -Force + $file = Get-Item $filename + $file.IsReadOnly = $true + Get-FormatData -TypeName * | Export-FormatData -Path $filename -Force + + $actual = @(Get-Content $filename)[0] + $actual | Should Not Be $unexpected + } + + It "should not overwrite the destination file with NoClobber" { + $filename = "TestDrive:\ExportFormatDataWithNoClobber.ps1xml" + Get-FormatData -TypeName * | Export-FormatData -LiteralPath $filename + + try + { + Get-FormatData -TypeName * | Export-FormatData -LiteralPath $filename -NoClobber + } + catch + { + $exportFormatError = $_ + } + + $exportFormatError.FullyQualifiedErrorId | Should Be 'NoClobber,Microsoft.PowerShell.Commands.ExportFormatDataCommand' + } + } +} diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/object.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/object.tests.ps1 new file mode 100644 index 0000000000..496917101b --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/object.tests.ps1 @@ -0,0 +1,100 @@ +Describe "Object cmdlets" -Tags 'innerloop', 'P1', 'RI' { + Context "Group-Object" { + It "AsHashtable returns a hashtable" { + $result = Get-Process | Group-Object -Property ProcessName -AsHashTable + $result["powershell"].Count | Should BeGreaterThan 0 + } + + It "AsString returns a string" { + $processes = Get-Process | Group-Object -Property ProcessName -AsHashTable -AsString + $result = $processes.Keys | ForEach-Object {$_.GetType()} + $result[0].Name | Should Be "String" + } + } + + Context "Tee-Object" { + It "with literal path" { + $path = "TestDrive:\[TeeObjectLiteralPathShouldWorkForSpecialFilename].txt" + Write-Output "Test" | Tee-Object -LiteralPath $path | Tee-Object -Variable TeeObjectLiteralPathShouldWorkForSpecialFilename + $TeeObjectLiteralPathShouldWorkForSpecialFilename | Should Be (Get-Content -LiteralPath $path) + } + } +} + +Describe "Object cmdlets" -Tags 'DRT' { + Context "Measure-Object" { + BeforeAll { + ## Powershell language prefers , as an array seperator without "". + ## If a number has comma in them it considers it to be the 1000 seperator like "1,000". + ## In de-DE language the comma is used as decimal point, but powershell still uses it as a 1000 seperator. + ## In case the number has a comma, it is ignored. So, "99,1" becomes 991. + ## To work around that behavior, we use ToString() on the expected answer and . for decimal in the input. + + $firstValue = "9995788.71" + $expectedFirstValue = $null + $null = [System.Management.Automation.LanguagePrimitives]::TryConvertTo($firstValue, [double], [cultureinfo]::InvariantCulture, [ref] $expectedFirstValue) + $firstObject = new-object psobject + $firstObject | Add-Member -NotePropertyName Header -NotePropertyValue $firstValue + + $secondValue = "15847577.7" + $expectedSecondValue = $null + $null = [System.Management.Automation.LanguagePrimitives]::TryConvertTo($secondValue, [double], [cultureinfo]::InvariantCulture, [ref] $expectedSecondValue) + $secondObject = new-object psobject + $secondObject | Add-Member -NotePropertyName Header -NotePropertyValue $secondValue + + $testCases = @( + @{ data = @("abc","ABC","Def"); min = "abc"; max = "Def"}, + @{ data = @([datetime]::Today, [datetime]::Today.AddDays(-1)); min = ([datetime]::Today.AddDays(-1)).ToString() ; max = [datetime]::Today.ToString() } + @{ data = @(1,2,3,"ABC"); min = 1; max = "ABC"}, + @{ data = @(4,2,3,"ABC",1); min = 1; max = "ABC"}, + @{ data = @(4,2,3,"ABC",1,"DEF"); min = 1; max = "DEF"}, + @{ data = @("111 Test","19"); min = "111 Test"; max = "19"}, + @{ data = @("19", "111 Test"); min = "111 Test"; max = "19"}, + @{ data = @("111 Test",19); min = "111 Test"; max = 19}, + @{ data = @(19, "111 Test"); min = "111 Test"; max = 19}, + @{ data = @(100,2,3, "A", 1); min = 1; max = "A"}, + @{ data = @(4,2,3, "ABC", 1, "DEF"); min = 1; max = "DEF"}, + @{ data = @("abc",[Datetime]::Today,"def"); min = [Datetime]::Today.ToString(); max = "def"} + ) + } + + It "can compare string representation for minimum" { + $minResult = $firstObject, $secondObject | Measure-Object Header -Minimum + $minResult.Minimum.ToString() | Should Be $expectedFirstValue.ToString() + } + + It "can compare string representation for maximum" { + $maxResult = $firstObject, $secondObject | Measure-Object Header -Maximum + $maxResult.Maximum.ToString() | Should Be $expectedSecondValue.ToString() + } + + It 'correctly find minimum of ()' -TestCases $testCases { + param($data, $min, $max) + + $output = $data | Measure-Object -Minimum + $output.Minimum.ToString() | Should Be $min + } + + It 'correctly find maximum of ()' -TestCases $testCases { + param($data, $min, $max) + + $output = $data | Measure-Object -Maximum + $output.Maximum.ToString() | Should Be $max + } + + It 'returns a GenericMeasureInfoObject' { + $gmi = 1,2,3 | measure-object -max -min + $gmi.GetType().FullName | Should Be 'Microsoft.PowerShell.Commands.GenericMeasureInfo' + } + + It 'should return correct error for non-numeric input' { + $gmi = "abc",[Datetime]::Now | measure -sum -max -ev err -ea silentlycontinue + $err | % { $_.FullyQualifiedErrorId | Should Be 'NonNumericInputObject,Microsoft.PowerShell.Commands.MeasureObjectCommand' } + } + + It 'should have the correct count' { + $gmi = "abc",[Datetime]::Now | measure -sum -max -ev err -ea silentlycontinue + $gmi.Count | Should Be 2 + } + } +} \ No newline at end of file diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/string.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/string.tests.ps1 new file mode 100644 index 0000000000..0282df288c --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/string.tests.ps1 @@ -0,0 +1,61 @@ +Describe "String cmdlets" -Tags 'innerloop', 'P1', 'RI' { + Context "Select-String" { + BeforeAll { + $fileName = New-Item 'TestDrive:\selectStr[ingLi]teralPath.txt' + "abc" | Out-File -LiteralPath $fileName.fullname + "bcd" | Out-File -LiteralPath $fileName.fullname -Append + "cde" | Out-File -LiteralPath $fileName.fullname -Append + + $fileNameWithDots = $fileName.FullName.Replace("\", "\.\") + + $tempFile = New-TemporaryFile + "abc" | Out-File -LiteralPath $tempFile.fullname + "bcd" | Out-File -LiteralPath $tempFile.fullname -Append + "cde" | Out-File -LiteralPath $tempFile.fullname -Append + $driveLetter = $tempFile.PSDrive.Name + $fileNameAsNetworkPath = "\\localhost\$driveLetter`$" + $tempFile.FullName.SubString(2) + + Push-Location "$fileName\.." + } + + AfterAll { + Remove-Item $tempFile -Force -ErrorAction SilentlyContinue + Pop-Location + } + + It "LiteralPath with relative path" { + (select-string -LiteralPath (Get-Item -LiteralPath $fileName).Name "b").count | Should Be 2 + } + + It "LiteralPath with absolute path" { + (select-string -LiteralPath $fileName "b").count | Should Be 2 + } + + It "LiteralPath with dots in path" { + (select-string -LiteralPath $fileNameWithDots "b").count | Should Be 2 + } + + It "Network path" { + (select-string -LiteralPath $fileNameAsNetworkPath "b").count | Should Be 2 + } + + It "throws error for non filesystem providers" { + select-string -literalPath cert:\currentuser\my "a" -ErrorAction SilentlyContinue -ErrorVariable selectStringError + $selectStringError.FullyQualifiedErrorId | Should Be 'ProcessingFile,Microsoft.PowerShell.Commands.SelectStringCommand' + } + + It "throws parameter binding exception for invalid context" { + { select-string It $PSScriptRoot -Context -1,-1 } | Should Throw Context + } + + It "match object supports RelativePath method" { + $file = "Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1" + + $match = Select-String CmdletsToExport $pshome/$file + + $match.RelativePath($pshome) | Should Be $file + $match.RelativePath($pshome.ToLower()) | Should Be $file + $match.RelativePath($pshome.ToUpper()) | Should Be $file + } + } +} diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/typedata.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/typedata.tests.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..6e3288fc54aadf0c86a80cb1402bfe53c9b94207 GIT binary patch literal 10702 zcmeHNTT>%N6h6;Z`5&f2szAAId_-Jj$*x6NtO&S1tUdq<5H|@i35%%v*VXUqlaub5 zOwSCLtZ}ub!rV{yxqat5J^b}&Q`$0;GZ{)pPH~(_O^)5Qu{7mG#`q<;-;|j1a%<|UFIR8zPuo4|Lk(ks^FowuAS|A&W0VAdmD0q=*SyC&o|{> z+nM-kfRPf6%{&;pn5Fj;9BW=z@m@W6I*~65;xwM8M51)`SGUclcvmx8^KV_g1y249 zJ#*GrR%AXhKX388MXg~%o)s-BLj7LL6ZvWGm~!qiXGQAph+4EEpW{f+*PX9; z=DoCm*dUrQg6zpvSw(afX;z$-`TBDXc^24!|5%9>0e`?#V<7A-s#W)E4YN1T&SEvS zA421Hp@y0Xrity#^CKOLVLZhvoJo&kNL*@>o_&{{-CRA>`pxRK_j#Xw=tI%~cUS@VHf5a1TkJco z!V=#`*t8ZVcw^w6)484DoJ>G5a8_a%#j|YWd&p{GG%}RCa1vI1&9ydAw~H;tUd*?3 zXrN4t$hn1aX)$8nYoN>(EJchVw_qLYB2%`oDQ@fhRw6k$>pL4WoaJ+8;mZp1|KDWyF(0U!t#QdM#d*5Y8OIu(=UQFW6`yH0xqbwx`^4Bu|4g9$Q>Ig;Z|M=@{Fx z8Qk5LeMsxM)c|%_d^g01EZ@DGY|YY8-ZRYq3OW4-BQ4L&Z5g9)PI5c;7M}?3<;`$2 zN2|@LwWxzXqt1$g=E>~-F+BU(96bA*aGQ^3%Vd{%Hv9f!c{a`@LS*@$A#EVK7K0&$ zmBOznXm3Gu)n0?>+6S)ioGXl+`xx0>&czLN4L6lLadlLA&oS_u<1~R@9OWhUWAIlS zV+7{e$Fnz%uao0))K&caTH~SPGwg|a5$0~lQ^eV7653+6YUZ;w&n!$s_QZGPLdu%i zom0bE7H_P@*vYMYhq}X>)dBnK;GI^$`S)-Z?^eC-N3i-WtjqDpCqw<|0rrXH%(}j{ z2JElSI_ZnBrwL`7?~RYJviqm$-#ktq$Cf2o!isi+NYVZLu2w4C540{50W3;Pv%GyC&f6cz;7snWsNpp3KTwL?Ta)lDvg;5gw4(-Ru$EjhS zme#pwR}p3;{mf2oty11;M5&aps&locyerv(-? zlUzH;qscs=l{oZ(u3zv=&N;lvnB|drCBbUuwL?Wl5<5c1PBmW{Mwa)L@vl1h=#=HC zi{=H7%Vq;ZI>QJ<)wqANI_70nxwk`n3Vr?<{w>PIaNPWw^Iy$Bu0nGqfw;<*M_sd2 z*1+}76I|yir0;ZFm5|XQZ85XWW;b7Kv+9yvCAQH$u2n;@q6nW?wJGZS77gdh@rS(k z2Jx)5L%D>03HLtn^+(t4`Nf}E;rWiPw>3BZoa{Q5Glciqe{yY9zr`{(-e2#1KlYqPUw&W9;&xbt(vi)T zB=%5Ti9dzbmOr!v*8+HT=Ol=f7-PTnmJxB~MIKFD8zVKfls*by(*3XCCw@-zMWH)p>x*Z=?k literal 0 HcmV?d00001 diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/xml.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/xml.tests.ps1 new file mode 100644 index 0000000000..f2985945d4 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/xml.tests.ps1 @@ -0,0 +1,62 @@ +Describe "XML cmdlets" -Tags 'P1', 'RI' { + Context "Select-XML" { + BeforeAll { + $fileName = New-Item -Path 'TestDrive:\testSelectXml.xml' + Push-Location "$fileName\.." + "" | out-file -LiteralPath $fileName + " " | out-file -LiteralPath $fileName -Append + "" | out-file -LiteralPath $fileName -Append + + $fileNameWithDots = $fileName.FullName.Replace("\", "\.\") + + $driveLetter = [string]($fileName.FullName)[0] + $fileNameAsNetworkPath = "\\localhost\$driveLetter`$" + $fileName.FullName.SubString(2) + + class TestData + { + [string] $testName + [hashtable] $parameters + + TestData($name, $parameters) + { + $this.testName = $name + $this.parameters = $parameters + } + } + + $testcases = @() + $testcases += [TestData]::new('literalpath with relative paths', @{LiteralPath = $fileName.Name; XPath = 'Root'}) + $testcases += [TestData]::new('literalpath with absolute paths', @{LiteralPath = $fileName.FullName; XPath = 'Root'}) + $testcases += [TestData]::new('literalpath with path with dots', @{LiteralPath = $fileNameWithDots; XPath = 'Root'}) + $testcases += [TestData]::new('literalpath with network path', @{LiteralPath = $fileNameAsNetworkPath; XPath = 'Root'}) + $testcases += [TestData]::new('path with relative paths', @{Path = $fileName.Name; XPath = 'Root'}) + $testcases += [TestData]::new('path with absolute paths', @{Path = $fileName.FullName; XPath = 'Root'}) + $testcases += [TestData]::new('path with path with dots', @{Path = $fileNameWithDots; XPath = 'Root'}) + $testcases += [TestData]::new('path with network path', @{Path = $fileNameAsNetworkPath; XPath = 'Root'}) + } + + AfterAll { + Remove-Item -LiteralPath $fileName -Force -ErrorAction SilentlyContinue + Pop-Location + } + + $testcases | % { + + $params = $_.parameters + + It $_.testName { + @(Select-XML @params).Count | Should Be 1 + } + } + + It "literalpath with non filesystem path" { + Select-XML -literalPath cert:\currentuser\my "Root" -ErrorVariable selectXmlError -ErrorAction SilentlyContinue + $selectXmlError.FullyQualifiedErrorId | Should Be 'ProcessingFile,Microsoft.PowerShell.Commands.SelectXmlCommand' + } + + It "path with non filesystem path" { + Select-XML -Path cert:\currentuser\my "Root" -ErrorVariable selectXmlError -ErrorAction SilentlyContinue + $selectXmlError.FullyQualifiedErrorId | Should Be 'ProcessingFile,Microsoft.PowerShell.Commands.SelectXmlCommand' + } + } +} \ No newline at end of file