MegaBites-AI/Windows-powershell
0372
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3 4Import-Module HelpersCommon5 6Describe "Export-Csv" -Tags "CI" {7 BeforeAll {8 $testObject = @("test","object","array")9 $testCsv = Join-Path -Path $TestDrive -ChildPath "output.csv"10 $newLine = [environment]::NewLine11 $P1 = [pscustomobject]@{"P1" = "first"}12 $P2 = [pscustomobject]@{"P2" = "second"}13 $P11 = [pscustomobject]@{"P1" = "eleventh"}14 $testHashTable = @{ 'first' = "value1"; 'second' = $null; 'third' = "value3" }15 }16 17 AfterEach {18 Remove-Item -Path $testCsv -Force -ErrorAction SilentlyContinue19 }20 21 It "Should be able to be called without error" {22 { $testObject | Export-Csv -Path $testCsv -ErrorAction Stop } | Should -Not -Throw23 }24 25 It "Should throw if an output file isn't specified" {26 { $testObject | Export-Csv -ErrorAction Stop } | Should -Throw -ErrorId "CannotSpecifyPathAndLiteralPath,Microsoft.PowerShell.Commands.ExportCsvCommand"27 }28 29 It "Should be a string when exporting via pipe" {30 $testObject | Export-Csv -Path $testCsv -IncludeTypeInformation31 $results = Get-Content -Path $testCsv32 33 $results[0] | Should -BeExactly "#TYPE System.String"34 }35 36 It "Should be an object when exporting via the inputObject switch" {37 Export-Csv -InputObject $testObject -Path $testCsv -IncludeTypeInformation38 $results = Get-Content -Path $testCsv39 40 $results[0] | Should -BeExactly "#TYPE System.Object[]"41 }42 43 It "Should output a csv file containing a string of all the lengths of each element when piped input is used" {44 $testObject | Export-Csv -Path $testCsv -IncludeTypeInformation45 46 $first = "`"" + $testObject[0].Length.ToString() + "`""47 $second = "`"" + $testObject[1].Length.ToString() + "`""48 $third = "`"" + $testObject[2].Length.ToString() + "`""49 $expected = @("#TYPE System.String", "`"Length`"", $first , $second, $third)50 51 for ($i = 0; $i -lt $expected.Count; $i++) {52 $(Get-Content -Path $testCsv)[$i] | Should -Be $expected[$i]53 }54 }55 56 It "Does not include type information by default" {57 $testObject | Export-Csv -Path $testCsv58 $results = Get-Content -Path $testCsv59 60 $results[0] | Should -Not -Match ([regex]::Escape("System.String"))61 $results[0] | Should -Not -Match ([regex]::Escape("#TYPE"))62 }63 64 It "Does not include type information with -NoTypeInformation" {65 $testObject | Export-Csv -Path $testCsv -NoTypeInformation66 $results = Get-Content -Path $testCsv67 68 $results[0] | Should -Not -Match ([regex]::Escape("System.String"))69 $results[0] | Should -Not -Match ([regex]::Escape("#TYPE"))70 }71 72 It "Does not include headers with -NoHeader when exported and can imported with headers" {73 $P1 | Export-Csv -Path $testCsv -NoHeader74 $results = Get-Content -Path $testCsv75 $results | Should -BeExactly '"first"'76 $results = Import-Csv -Path $testCsv -Header "P1"77 $results[0].P1 | Should -BeExactly "first"78 }79 80 It "Does not include headers when imported with headers and exported using -NoHeader" {81 $P1 | Export-Csv -Path $testCsv82 (Import-Csv -Path $testCsv) | Export-Csv -Path $testCsv -NoHeader83 $results = Get-Content -Path $testCsv84 $results | Should -BeExactly '"first"'85 }86 87 It "Includes type information when -IncludeTypeInformation is supplied" {88 $testObject | Export-Csv -Path $testCsv -IncludeTypeInformation89 $results = Get-Content -Path $testCsv90 91 $results[0] | Should -BeExactly "#TYPE System.String"92 }93 94 It "Should support -LiteralPath parameter" {95 $testObject | Export-Csv -LiteralPath $testCsv96 $results = Import-Csv -Path $testCsv97 98 $results | Should -HaveCount 399 }100 101 It "Should overwrite file without -NoClobber parameter" {102 $P1 | Export-Csv -Path $testCsv103 $P2 | Export-Csv -Path $testCsv104 $results = Import-Csv -Path $testCsv105 106 $results.P2 | Should -BeExactly "second"107 }108 109 It "Should not overwrite file with -NoClobber parameter" {110 $P1 | Export-Csv -Path $testCsv111 { $P2 | Export-Csv -Path $testCsv -NoClobber} | Should -Throw -ErrorId "NoClobber,Microsoft.PowerShell.Commands.ExportCsvCommand"112 $results = Import-Csv -Path $testCsv113 114 $results.P1 | Should -BeExactly "first"115 }116 117 It "Should not overwrite read-only file without -Force parameter" -Skip:(Test-IsRoot) {118 $P1 | Export-Csv -Path $testCsv119 Set-ItemProperty -Path $testCsv -Name IsReadOnly -Value $true120 121 { $P2 | Export-Csv -Path $testCsv } | Should -Throw -ErrorId "FileOpenFailure,Microsoft.PowerShell.Commands.ExportCsvCommand"122 $results = Import-Csv -Path $testCsv123 124 $results.P1 | Should -BeExactly "first"125 }126 127 It "Should overwrite read-only file with -Force parameter" {128 $P1 | Export-Csv -Path $testCsv129 Set-ItemProperty -Path $testCsv -Name IsReadOnly -Value $true130 131 $P2 | Export-Csv -Path $testCsv -Force132 $results = Import-Csv -Path $testCsv133 134 $results.P2 | Should -BeExactly "second"135 }136 137 It "Should not export to file if -WhatIf parameter specified" {138 $P1 | Export-Csv -Path $testCsv -WhatIf139 $testCsv | Should -Not -Exist140 }141 142 It "Should append to file if -Append parameter specified" {143 $P1 | Export-Csv -Path $testCsv144 $P11 | Export-Csv -Path $testCsv -Append145 $results = Import-Csv -Path $testCsv146 147 $results[0].P1 | Should -BeExactly "first"148 $results[1].P1 | Should -BeExactly "eleventh"149 }150 151 # This test is not a duplicate of the previous one, since it covers a separate branch in code.152 It "Should append to empty file if -Append parameter specified" {153 New-Item -Path $testCsv -ItemType File | Out-Null154 155 $P11 | Export-Csv -Path $testCsv -Append156 $results = Import-Csv -Path $testCsv157 158 $results[0].P1 | Should -BeExactly "eleventh"159 }160 161 It "Should throw when appended property does not exist in existing .csv file" {162 $P1 | Export-Csv -Path $testCsv163 { $P2 | Export-Csv -Path $testCsv -Append -ErrorAction Stop } | Should -Throw -ErrorId "CannotAppendCsvWithMismatchedPropertyNames,Microsoft.PowerShell.Commands.ExportCsvCommand"164 $results = Import-Csv -Path $testCsv165 166 $results[0].P1 | Should -BeExactly "first"167 }168 169 It "Should append existing properties, add missing properties with empty value, and skip extra properties" {170 $object1 = [PSCustomObject]@{first = 1; second = 2}171 $object2 = [PSCustomObject]@{first = 11; third = 13}172 173 $object1 | Export-Csv -Path $testCsv174 $object2 | Export-Csv -Path $testCsv -Append -Force175 176 $results = Import-Csv -Path $testCsv177 178 $results[0].first | Should -BeExactly "1"179 $results[0].second | Should -BeExactly "2"180 $results[1].first | Should -BeExactly "11"181 $results[1].second | Should -BeNullOrEmpty182 $results[1].PSObject.properties.Name | Should -Not -Contain 'third'183 }184 185 It "Should throw when -Append and -NoHeader are specified together" {186 { $P1 | Export-Csv -Path $testCsv -Append -NoHeader -ErrorAction Stop } | Should -Throw -ErrorId "CannotSpecifyBothAppendAndNoHeader,Microsoft.PowerShell.Commands.ExportCsvCommand"187 }188 189 It "First line should be #TYPE if -IncludeTypeInformation used and pstypenames object property is empty" {190 $object = [PSCustomObject]@{first = 1}191 $pstypenames = $object.pstypenames | ForEach-Object -Process {$_}192 $pstypenames | ForEach-Object -Process {$object.pstypenames.Remove($_)}193 $object | Export-Csv -Path $testCsv -IncludeTypeInformation194 $content = Get-Content -Path $testCsv195 196 $content[0] | Should -BeExactly '#TYPE'197 }198 199 # If type starts with CSV: Export-CSV should remove it. This would happen when you export200 # an imported object. Import-Csv adds CSV: prefix to the type.201 It "Should remove 'CSV:' from the type name" {202 $object = [PSCustomObject]@{first = 1}203 $object.pstypenames.Insert(0, "CSV:TheType")204 $object | Export-Csv -Path $testCsv -IncludeTypeInformation205 $result = Get-Content -Path $testCsv206 207 $result[0] | Should -BeExactly "#TYPE TheType"208 }209 210 It "Should escape double quote with another double quote" {211 $object = [PSCustomObject]@{first = 'Double quote " in the middle.'}212 $object | Export-Csv -Path $testCsv213 $result = Get-Content -Path $testCsv214 215 $result[1] | Should -BeExactly '"Double quote "" in the middle."'216 }217 218 It "Test basic function works well" {219 $in = [pscustomobject]@{ "P1" = "V11"; "P2" = "V12"; "P3" = "V13" }220 $in | Export-Csv -Path $testCsv -NoTypeInformation221 $results = Import-Csv -Path $testCsv222 223 $results.P1 | Should -BeExactly "V11"224 $results.P2 | Should -BeExactly "V12"225 $results.P3 | Should -BeExactly "V13"226 }227 228 It "Test if it works with special character" {229 $v3 = "abc" + $newLine + "foo"230 $in = [pscustomobject]@{ "P1" = " "; "P2" = "abc,foo"; "P3" = $v3}231 $in | Export-Csv -Path $testCsv -NoTypeInformation232 $results = Import-Csv -Path $testCsv233 234 $results.P1 | Should -BeExactly " "235 $results.P2 | Should -BeExactly "abc,foo"236 $results.P3 | Should -BeExactly $v3237 }238 239 It "Test export-csv with a useculture flag" {240 $outputFilesDir = Join-Path -Path $TestDrive -ChildPath "Monad"241 $fileToGenerate = Join-Path -Path $outputFilesDir -ChildPath "CSVTests.csv"242 $delimiter = (Get-Culture).TextInfo.ListSeparator243 New-Item -Path $outputFilesDir -ItemType Directory -Force244 Get-Item -Path $outputFilesDir | Export-Csv -Path $fileToGenerate -UseCulture -NoTypeInformation245 $contents = Get-Content -Path $fileToGenerate246 247 $contents.Count | Should -Be 2248 $contents[0].Contains($delimiter) | Should -BeTrue249 $contents[1].Contains($delimiter) | Should -BeTrue250 }251 252 It "Should not throw when exporting hashtable with property that has null value"{253 { $testHashTable | Export-Csv -Path $testCsv } | Should -Not -Throw254 }255 256 It "Should not throw when exporting PSCustomObject with property that has null value"{257 $testObject = [pscustomobject]$testHashTable258 { $testObject | Export-Csv -Path $testCsv } | Should -Not -Throw259 }260 261 It "Export hashtable with null and non-null values"{262 $testHashTable | Export-Csv -Path $testCsv263 $result2 = Import-CSV -Path $testCsv264 265 $result2.first | Should -BeExactly "value1"266 $result2.second | Should -BeNullOrEmpty267 $result2.third | Should -BeExactly "value3"268 }269 270 It "Export hashtable with non-null values"{271 $testTable = @{ 'first' = "value1"; 'second' = "value2" }272 $testTable | Export-Csv -Path $testCsv273 $results = Import-CSV -Path $testCsv274 275 $results.first | Should -BeExactly "value1"276 $results.second | Should -BeExactly "value2"277 }278 279 Context "UseQuotes parameter" {280 281 # A minimum of tests. The rest are in ConvertTo-Csv.Tests.ps1282 283 BeforeAll {284 $Name = "Hello"; $Data = "World";285 $testOutputObject = [pscustomobject]@{ FirstColumn = $Name; SecondColumn = $Data }286 $testFile = Join-Path -Path $TestDrive -ChildPath "output.csv"287 $testFile2 = Join-Path -Path $TestDrive -ChildPath "output2.csv"288 }289 290 It "UseQuotes Always" {291 $testOutputObject | Export-Csv -Path $testFile -UseQuotes Always -Delimiter ','292 $result = Get-Content -Path $testFile293 294 $result[0] | Should -BeExactly "`"FirstColumn`",`"SecondColumn`""295 $result[1] | Should -BeExactly "`"Hello`",`"World`""296 }297 298 It "UseQuotes Always is default" {299 $testOutputObject | Export-Csv -Path $testFile -UseQuotes Always -Delimiter ','300 $result = Get-Content -Raw -Path $testFile301 $testOutputObject | Export-Csv -Path $testFile2 -Delimiter ','302 $result2 = Get-Content -Raw -Path $testFile2303 304 $result | Should -BeExactly $result2305 }306 }307}308 