Fix LiteralPath in Import-Csv to bind to Get-ChildItem output (#8277)

Added new tests.
This commit is contained in:
Ilya 2019-01-09 18:49:15 +05:00 committed by GitHub
parent 73716e9792
commit 6647b29f41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 13 deletions

View file

@ -509,7 +509,7 @@ namespace Microsoft.PowerShell.Commands
/// <summary> /// <summary>
/// Implements Import-Csv command. /// Implements Import-Csv command.
/// </summary> /// </summary>
[Cmdlet(VerbsData.Import, "Csv", DefaultParameterSetName = "Delimiter", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=113341")] [Cmdlet(VerbsData.Import, "Csv", DefaultParameterSetName = "DelimiterPath", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=113341")]
public sealed public sealed
class class
ImportCsvCommand : PSCmdlet ImportCsvCommand : PSCmdlet
@ -519,14 +519,16 @@ namespace Microsoft.PowerShell.Commands
/// <summary> /// <summary>
/// Property that sets delimiter. /// Property that sets delimiter.
/// </summary> /// </summary>
[Parameter(Position = 1, ParameterSetName = "Delimiter")] [Parameter(Position = 1, ParameterSetName = "DelimiterPath")]
[Parameter(Position = 1, ParameterSetName = "DelimiterLiteralPath")]
[ValidateNotNull] [ValidateNotNull]
public char Delimiter { get; set; } public char Delimiter { get; set; }
/// <summary> /// <summary>
/// Mandatory file name to read from. /// Mandatory file name to read from.
/// </summary> /// </summary>
[Parameter(Position = 0, ValueFromPipeline = true)] [Parameter(Position = 0, ParameterSetName = "DelimiterPath", Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[Parameter(Position = 0, ParameterSetName = "CulturePath", Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty] [ValidateNotNullOrEmpty]
public string[] Path public string[] Path
{ {
@ -548,7 +550,8 @@ namespace Microsoft.PowerShell.Commands
/// <summary> /// <summary>
/// The literal path of the mandatory file name to read from. /// The literal path of the mandatory file name to read from.
/// </summary> /// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)] [Parameter(ParameterSetName = "DelimiterLiteralPath", Mandatory = true, ValueFromPipelineByPropertyName = true)]
[Parameter(ParameterSetName = "CultureLiteralPath", Mandatory = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty] [ValidateNotNullOrEmpty]
[Alias("PSPath", "LP")] [Alias("PSPath", "LP")]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
@ -571,7 +574,8 @@ namespace Microsoft.PowerShell.Commands
/// <summary> /// <summary>
/// Property that sets UseCulture parameter. /// Property that sets UseCulture parameter.
/// </summary> /// </summary>
[Parameter(ParameterSetName = "UseCulture", Mandatory = true)] [Parameter(ParameterSetName = "CulturePath", Mandatory = true)]
[Parameter(ParameterSetName = "CultureLiteralPath", Mandatory = true)]
[ValidateNotNull] [ValidateNotNull]
public SwitchParameter UseCulture public SwitchParameter UseCulture
{ {
@ -664,7 +668,7 @@ namespace Microsoft.PowerShell.Commands
/// <summary> /// <summary>
/// Implements ConvertTo-Csv command. /// Implements ConvertTo-Csv command.
/// </summary> /// </summary>
[Cmdlet(VerbsData.ConvertTo, "Csv", DefaultParameterSetName = "Delimiter", [Cmdlet(VerbsData.ConvertTo, "Csv", DefaultParameterSetName = "DelimiterPath",
HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135203", RemotingCapability = RemotingCapability.None)] HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135203", RemotingCapability = RemotingCapability.None)]
[OutputType(typeof(string))] [OutputType(typeof(string))]
public sealed class ConvertToCsvCommand : BaseCsvWritingCommand public sealed class ConvertToCsvCommand : BaseCsvWritingCommand
@ -754,7 +758,7 @@ namespace Microsoft.PowerShell.Commands
/// <summary> /// <summary>
/// Implements ConvertFrom-Csv command. /// Implements ConvertFrom-Csv command.
/// </summary> /// </summary>
[Cmdlet(VerbsData.ConvertFrom, "Csv", DefaultParameterSetName = "Delimiter", [Cmdlet(VerbsData.ConvertFrom, "Csv", DefaultParameterSetName = "DelimiterPath",
HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135201", RemotingCapability = RemotingCapability.None)] HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135201", RemotingCapability = RemotingCapability.None)]
public sealed public sealed
class class
@ -765,7 +769,7 @@ namespace Microsoft.PowerShell.Commands
/// <summary> /// <summary>
/// Property that sets delimiter. /// Property that sets delimiter.
/// </summary> /// </summary>
[Parameter(Position = 1, ParameterSetName = "Delimiter")] [Parameter(Position = 1, ParameterSetName = "DelimiterPath")]
[ValidateNotNull] [ValidateNotNull]
[ValidateNotNullOrEmpty] [ValidateNotNullOrEmpty]
public char Delimiter { get; set; } public char Delimiter { get; set; }
@ -773,7 +777,8 @@ namespace Microsoft.PowerShell.Commands
///<summary> ///<summary>
///Culture switch for csv conversion ///Culture switch for csv conversion
///</summary> ///</summary>
[Parameter(ParameterSetName = "UseCulture", Mandatory = true)] [Parameter(ParameterSetName = "CulturePath", Mandatory = true)]
[Parameter(ParameterSetName = "CultureLiteralPath", Mandatory = true)]
[ValidateNotNull] [ValidateNotNull]
[ValidateNotNullOrEmpty] [ValidateNotNullOrEmpty]
public SwitchParameter UseCulture { get; set; } public SwitchParameter UseCulture { get; set; }
@ -1702,6 +1707,8 @@ namespace Microsoft.PowerShell.Commands
switch (ParameterSetName) switch (ParameterSetName)
{ {
case "Delimiter": case "Delimiter":
case "DelimiterPath":
case "DelimiterLiteralPath":
// if delimiter is not given, it should take , as value // if delimiter is not given, it should take , as value
if (Delimiter == '\0') if (Delimiter == '\0')
{ {
@ -1710,6 +1717,8 @@ namespace Microsoft.PowerShell.Commands
break; break;
case "UseCulture": case "UseCulture":
case "CulturePath":
case "CultureLiteralPath":
if (UseCulture == true) if (UseCulture == true)
{ {
// ListSeparator is apparently always a character even though the property returns a string, checked via: // ListSeparator is apparently always a character even though the property returns a string, checked via:

View file

@ -41,16 +41,50 @@ Describe "Import-Csv Double Quote Delimiter" -Tags "CI" {
} }
It "Should handle <name>" -TestCases @( It "Should handle <name> and bind to LiteralPath from pipeline" -TestCases @(
@{ name = "quote with empty value" ; expectedHeader = "a1,H1,a3"; file = "EmptyValue.csv" ; content = $empyValueCsv ; delimiter = '"' } @{ name = "quote with empty value" ; expectedHeader = "a1,H1,a3"; file = "EmptyValue.csv" ; content = $empyValueCsv ; delimiter = '"' }
@{ name = "quote with value" ; expectedHeader = "a1,a2,a3"; file = "WithValue.csv" ; content = $withValueCsv ; delimiter = '"' } @{ name = "quote with value" ; expectedHeader = "a1,a2,a3"; file = "WithValue.csv" ; content = $withValueCsv ; delimiter = '"' }
@{ name = "value enclosed in quote" ; expectedHeader = "a1,a2,a3"; file = "QuotedCharacter.csv" ; content = $quotedCharacterCsv ; delimiter = ',' } @{ name = "value enclosed in quote" ; expectedHeader = "a1,a2,a3"; file = "QuotedCharacter.csv" ; content = $quotedCharacterCsv ; delimiter = ',' }
){ ){
param($expectedHeader, $file, $content, $delimiter) param($expectedHeader, $file, $content, $delimiter)
Set-Content testdrive:/$file -Value $content
$returnObject = Import-Csv -Path testdrive:/$file -Delimiter $delimiter $testPath = Join-Path $TestDrive $file
Set-Content $testPath -Value $content
$returnObject = Get-ChildItem -Path $testPath | Import-Csv -Delimiter $delimiter
$actualHeader = $returnObject[0].psobject.Properties.name -join ',' $actualHeader = $returnObject[0].psobject.Properties.name -join ','
$actualHeader | Should -Be $expectedHeader $actualHeader | Should -BeExactly $expectedHeader
$returnObject = $testPath | Import-Csv -Delimiter $delimiter
$actualHeader = $returnObject[0].psobject.Properties.name -join ','
$actualHeader | Should -BeExactly $expectedHeader
$returnObject = [pscustomobject]@{ LiteralPath = $testPath } | Import-Csv -Delimiter $delimiter
$actualHeader = $returnObject[0].psobject.Properties.name -join ','
$actualHeader | Should -BeExactly $expectedHeader
}
It "Should handle <name> and bind to Path from pipeline" -TestCases @(
@{ name = "quote with empty value" ; expectedHeader = "a1,H1,a3"; file = "EmptyValue.csv" ; content = $empyValueCsv ; delimiter = '"' }
@{ name = "quote with value" ; expectedHeader = "a1,a2,a3"; file = "WithValue.csv" ; content = $withValueCsv ; delimiter = '"' }
@{ name = "value enclosed in quote" ; expectedHeader = "a1,a2,a3"; file = "QuotedCharacter.csv" ; content = $quotedCharacterCsv ; delimiter = ',' }
){
param($expectedHeader, $file, $content, $delimiter)
$testPath = Join-Path $TestDrive $file
Set-Content $testPath -Value $content
$returnObject = Get-ChildItem -Path $testPath | Import-Csv -Delimiter $delimiter
$actualHeader = $returnObject[0].psobject.Properties.name -join ','
$actualHeader | Should -BeExactly $expectedHeader
$returnObject = $testPath | Import-Csv -Delimiter $delimiter
$actualHeader = $returnObject[0].psobject.Properties.name -join ','
$actualHeader | Should -BeExactly $expectedHeader
$returnObject = [pscustomobject]@{ Path = $testPath } | Import-Csv -Delimiter $delimiter
$actualHeader = $returnObject[0].psobject.Properties.name -join ','
$actualHeader | Should -BeExactly $expectedHeader
} }
} }