From 9fd600448c41d8dbccc50bc30858938e35aeb96a Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Sat, 21 Oct 2017 04:41:46 -0500 Subject: [PATCH] Make -NoTypeInformation Default on Export-Csv and ConvertTo-Csv (#5164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit •Sets -NoTypeInformation as the default behavior for Export-Csv and ConvertTo-Csv •Hides the -NoTypeInformation parameter switch •Adds -IncludeTypeInformation switch to Export-Csv and ConvertTo-Csv to enable legacy behavior •Provides a terminating error when both -NoTypeInformation and -IncludeTypeInformation are supplied •adds tests for the new behavior •fixes existing tests to align with new behavior The new behavior will need to be documented. --- .../commands/utility/CSVCommands.cs | 32 +++++++++------- .../resources/CsvCommandStrings.resx | 3 ++ .../ConvertTo-Csv.Tests.ps1 | 37 ++++++++++++++++--- .../Export-Csv.Tests.ps1 | 33 +++++++++++++++-- .../Import-Csv.Tests.ps1 | 2 +- 5 files changed, 83 insertions(+), 24 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs index 6313a9a5dd..ca7752da8b 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs @@ -67,22 +67,18 @@ namespace Microsoft.PowerShell.Commands } /// - /// NoTypeInformation : should the #TYPE line be generated + /// IncludeTypeInformation : The #TYPE line should be generated. Default is false. Cannot specify with NoTypeInformation. /// [Parameter] + [Alias("ITI")] + public SwitchParameter IncludeTypeInformation { get; set; } + + /// + /// NoTypeInformation : The #TYPE line should not be generated. Default is true. Cannot specify with IncludeTypeInformation. + /// + [Parameter(DontShow = true)] [Alias("NTI")] - public SwitchParameter NoTypeInformation - { - get - { - return _noTypeInformation; - } - set - { - _noTypeInformation = value; - } - } - private bool _noTypeInformation; + public SwitchParameter NoTypeInformation { get; set; } = true; #endregion Command Line Parameters @@ -100,6 +96,16 @@ namespace Microsoft.PowerShell.Commands /// protected override void BeginProcessing() { + if (this.MyInvocation.BoundParameters.ContainsKey(nameof(IncludeTypeInformation)) && this.MyInvocation.BoundParameters.ContainsKey(nameof(NoTypeInformation))) + { + InvalidOperationException exception = new InvalidOperationException(CsvCommandStrings.CannotSpecifyIncludeTypeInformationAndNoTypeInformation); + ErrorRecord errorRecord = new ErrorRecord(exception, "CannotSpecifyIncludeTypeInformationAndNoTypeInformation", ErrorCategory.InvalidData, null); + this.ThrowTerminatingError(errorRecord); + } + if (this.MyInvocation.BoundParameters.ContainsKey("IncludeTypeInformation")) + { + NoTypeInformation = !IncludeTypeInformation; + } _delimiter = ImportExportCSVHelper.SetDelimiter(this, ParameterSetName, _delimiter, UseCulture); } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resx index 6616139c9b..8d0ae2da59 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resx @@ -127,6 +127,9 @@ Reviewed by TArcher on 2010-06-29. + + You must specify either the -IncludeTypeInformation or -NoTypeInformation parameters, but not both. + You must specify either the -Path or -LiteralPath parameters, but not both. diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Csv.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Csv.Tests.ps1 index 31a05bd73c..11de104cbd 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Csv.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Csv.Tests.ps1 @@ -2,7 +2,7 @@ Describe "ConvertTo-Csv DRT Unit Tests" -Tags "CI" { $inputObject = [pscustomobject]@{ First = 1; Second = 2 } It "Test convertto-csv with psobject pipelined" { - $returnObject = $inputObject | ConvertTo-Csv + $returnObject = $inputObject | ConvertTo-Csv -IncludeTypeInformation $returnObject.Count | Should Be 3 $returnObject[0] | Should Be "#TYPE System.Management.Automation.PSCustomObject" $returnObject[1] | Should Be "`"First`",`"Second`"" @@ -18,7 +18,7 @@ Describe "ConvertTo-Csv DRT Unit Tests" -Tags "CI" { It "Test convertto-csv with a useculture flag" { #The default value is ',' - $returnObject = $inputObject | ConvertTo-Csv -UseCulture + $returnObject = $inputObject | ConvertTo-Csv -UseCulture -IncludeTypeInformation $returnObject.Count | Should Be 3 $returnObject[0] | Should Be "#TYPE System.Management.Automation.PSCustomObject" $returnObject[1] | Should Be "`"First`",`"Second`"" @@ -27,7 +27,7 @@ Describe "ConvertTo-Csv DRT Unit Tests" -Tags "CI" { It "Test convertto-csv with Delimiter" { #The default value is ',' - $returnObject = $inputObject | ConvertTo-Csv -Delimiter ";" + $returnObject = $inputObject | ConvertTo-Csv -Delimiter ";" -IncludeTypeInformation $returnObject.Count | Should Be 3 $returnObject[0] | Should Be "#TYPE System.Management.Automation.PSCustomObject" $returnObject[1] | Should Be "`"First`";`"Second`"" @@ -50,22 +50,47 @@ Describe "ConvertTo-Csv" -Tags "CI" { } It "Should return the type of data in the first element of the output array" { - $result = $testObject | ConvertTo-Csv + $result = $testObject | ConvertTo-Csv -IncludeTypeInformation $result[0] | Should Be "#TYPE System.Management.Automation.PSCustomObject" } It "Should return the column info in the second element of the output array" { - $result = $testObject | ConvertTo-Csv + $result = $testObject | ConvertTo-Csv -IncludeTypeInformation $result[1] | Should Match "`"FirstColumn`"" $result[1] | Should Match "`"SecondColumn`"" } It "Should return the data as a comma-separated list in the third element of the output array" { - $result = $testObject | ConvertTo-Csv + $result = $testObject | ConvertTo-Csv -IncludeTypeInformation $result[2] | Should Match "`"Hello`"" $result[2] | Should Match "`"World`"" } + It "Includes type information when -IncludeTypeInformation is supplied" { + $result = $testObject | ConvertTo-Csv -IncludeTypeInformation + + ($result -split ([Environment]::NewLine))[0] | Should BeExactly "#TYPE System.Management.Automation.PSCustomObject" + } + + It "Does not include type information by default" { + $result = $testObject | ConvertTo-Csv + + $result | Should Not Match ([regex]::Escape('System.Management.Automation.PSCustomObject')) + $result | Should Not Match ([regex]::Escape('#TYPE')) + } + + It "Does not include type information with -NoTypeInformation" { + $result = $testObject | ConvertTo-Csv -NoTypeInformation + + $result | Should Not Match ([regex]::Escape('System.Management.Automation.PSCustomObject')) + $result | Should Not Match ([regex]::Escape('#TYPE')) + } + + It "Does not support -IncludeTypeInformation and -NoTypeInformation at the same time" { + { $testObject | ConvertTo-Csv -IncludeTypeInformation -NoTypeInformation } | + ShouldBeErrorId "CannotSpecifyIncludeTypeInformationAndNoTypeInformation,Microsoft.PowerShell.Commands.ConvertToCsvCommand" + } + } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Export-Csv.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Export-Csv.Tests.ps1 index 3052b04d42..3f9b3f4a55 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Export-Csv.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Export-Csv.Tests.ps1 @@ -15,7 +15,7 @@ Describe "Export-Csv" -Tags "CI" { } It "Should be a string when exporting via pipe" { - $testObject | Export-Csv $testCsv + $testObject | Export-Csv $testCsv -IncludeTypeInformation $piped = Get-Content $testCsv @@ -23,15 +23,15 @@ Describe "Export-Csv" -Tags "CI" { } It "Should be an object when exporting via the inputObject switch" { - Export-Csv -InputObject $testObject -Path $testCsv + Export-Csv -InputObject $testObject -Path $testCsv -IncludeTypeInformation - $switch = Get-Content $testCsv + $switch = Get-Content $testCsv $switch[0] | Should Match ".Object" } It "Should output a csv file containing a string of all the lengths of each element when piped input is used" { - $testObject | Export-Csv -Path $testCsv + $testObject | Export-Csv -Path $testCsv -IncludeTypeInformation $first = "`"" + $testObject[0].Length.ToString() + "`"" $second = "`"" + $testObject[1].Length.ToString() + "`"" @@ -63,6 +63,31 @@ Describe "Export-Csv" -Tags "CI" { # Clean up after yourself Remove-Item $aliasObject -Force } + + It "Does not include type information by default" { + $testObject | Export-Csv -Path $testCsv + + $(Get-Content $testCsv)[0] | Should Not Match ([regex]::Escape("System.String")) + $(Get-Content $testCsv)[0] | Should Not Match ([regex]::Escape("#TYPE")) + } + + It "Does not include type information with -NoTypeInformation" { + $testObject | Export-Csv -Path $testCsv -NoTypeInformation + + $(Get-Content $testCsv)[0] | Should Not Match ([regex]::Escape("System.String")) + $(Get-Content $testCsv)[0] | Should Not Match ([regex]::Escape("#TYPE")) + } + + It "Includes type information when -IncludeTypeInformation is supplied" { + $testObject | Export-Csv -Path $testCsv -IncludeTypeInformation + + $(Get-Content $testCsv)[0] | Should BeExactly "#TYPE System.String" + } + + It "Does not support -IncludeTypeInformation and -NoTypeInformation at the same time" { + { $testObject | Export-Csv -Path $testCsv -IncludeTypeInformation -NoTypeInformation } | + ShouldBeErrorId "CannotSpecifyIncludeTypeInformationAndNoTypeInformation,Microsoft.PowerShell.Commands.ExportCsvCommand" + } } Describe "Export-Csv DRT Unit Tests" -Tags "CI" { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Import-Csv.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Import-Csv.Tests.ps1 index 61ea6b5322..fc3144ad78 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Import-Csv.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Import-Csv.Tests.ps1 @@ -79,7 +79,7 @@ Describe "Import-Csv #Type Tests" -Tags "CI" { $testfile = Join-Path $TestDrive -ChildPath "testfile.csv" Remove-Item -Path $testfile -Force -ErrorAction SilentlyContinue $processlist = (Get-Process)[0..1] - $processlist | Export-Csv -Path $testfile -Force + $processlist | Export-Csv -Path $testfile -Force -IncludeTypeInformation # Import-Csv add "CSV:" before actual type $expectedProcessType = "CSV:System.Diagnostics.Process" }