Fix -NoEnumerate behaviour in Write-Output (#9069)

Fix is to preserve input collection type in output.
The regression was caused by #2038
This commit is contained in:
Joel Sallow (/u/ta11ow) 2019-03-13 04:54:12 -04:00 committed by Ilya
parent e75bd1482f
commit 18d5037ad2
2 changed files with 49 additions and 56 deletions

View file

@ -12,49 +12,32 @@ namespace Microsoft.PowerShell.Commands
[Cmdlet(VerbsCommunications.Write, "Output", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=113427", RemotingCapability = RemotingCapability.None)]
public sealed class WriteOutputCommand : PSCmdlet
{
private PSObject[] _inputObjects = null;
/// <summary>
/// Holds the list of objects to be written.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true, ValueFromRemainingArguments = true)]
[AllowNull]
[AllowEmptyCollection]
public PSObject[] InputObject
{
get { return _inputObjects; }
set { _inputObjects = value; }
}
public PSObject InputObject { get; set; }
/// <summary>
/// Prevents Write-Output from unravelling collections passed to the InputObject parameter.
/// </summary>
[Parameter()]
public SwitchParameter NoEnumerate
{
get;
set;
}
[Parameter]
public SwitchParameter NoEnumerate { get; set; }
/// <summary>
/// This method implements the ProcessRecord method for Write-output command.
/// </summary>
protected override void ProcessRecord()
{
if (_inputObjects == null)
if (InputObject == null)
{
WriteObject(_inputObjects);
WriteObject(InputObject);
return;
}
bool enumerate = true;
if (NoEnumerate.IsPresent)
{
enumerate = false;
}
WriteObject(_inputObjects, enumerate);
WriteObject(InputObject, !NoEnumerate.IsPresent);
}
}
#endregion

View file

@ -18,60 +18,70 @@ Describe "Write-Output DRT Unit Tests" -Tags "CI" {
It "Works with NoEnumerate switch" {
$objectWritten = 1, 2.2, @("John", "Smith", 10), "abc"
[string]$s = Write-Output $objectWritten -NoEnumerate 6>&1
[string]$s = Write-Output $objectWritten -NoEnumerate 6>&1
$s | Should -Be '1 2.2 System.Object[] abc'
}
It "Preserves the input collection type and contents with -NoEnumerate" {
$List = [System.Collections.Generic.List[string]]::new( [string[]]@("test", "one", "two") )
$ObjectWritten = Write-Output $List -NoEnumerate
$ObjectWritten.GetType() | Should -Be ([System.Collections.Generic.List[string]])
$ObjectWritten[0] | Should -BeExactly "test"
$ObjectWritten[1] | Should -BeExactly "one"
$ObjectWritten[2] | Should -BeExactly "two"
}
}
Describe "Write-Output" -Tags "CI" {
$testString = $testString
Context "Input Tests" {
It "Should allow piped input" {
{ $testString | Write-Output } | Should -Not -Throw
}
It "Should allow piped input" {
{ $testString | Write-Output } | Should -Not -Throw
}
It "Should write output to the output stream when using piped input" {
$testString | Write-Output | Should -Be $testString
}
It "Should write output to the output stream when using piped input" {
$testString | Write-Output | Should -Be $testString
}
It "Should use inputobject switch" {
{ Write-Output -InputObject $testString } | Should -Not -Throw
}
It "Should use inputobject switch" {
{ Write-Output -InputObject $testString } | Should -Not -Throw
}
It "Should write output to the output stream when using inputobject switch" {
Write-Output -InputObject $testString | Should -Be $testString
}
It "Should write output to the output stream when using inputobject switch" {
Write-Output -InputObject $testString | Should -Be $testString
}
It "Should be able to write to a variable" {
Write-Output -InputObject $testString -OutVariable var
$var | Should -Be $testString
}
It "Should be able to write to a variable" {
Write-Output -InputObject $testString -OutVariable var
$var | Should -Be $testString
}
}
Context "Pipeline Command Tests" {
It "Should send object to the next command in the pipeline" {
Write-Output -InputObject (1+1) | Should -Be 2
}
It "Should send object to the next command in the pipeline" {
Write-Output -InputObject (1 + 1) | Should -Be 2
}
It "Should have the same result between inputobject switch and piped input" {
Write-Output -InputObject (1+1) | Should -Be 2
It "Should have the same result between inputobject switch and piped input" {
Write-Output -InputObject (1 + 1) | Should -Be 2
1+1 | Write-Output | Should -Be 2
}
1 + 1 | Write-Output | Should -Be 2
}
}
Context "Enumerate Objects" {
$enumerationObject = @(1,2,3)
It "Should see individual objects when not using the NoEnumerate switch" {
$singleCollection = $(Write-Output $enumerationObject| Measure-Object).Count
$enumerationObject = @(1, 2, 3)
It "Should see individual objects when not using the NoEnumerate switch" {
$singleCollection = $(Write-Output $enumerationObject| Measure-Object).Count
$singleCollection | Should -Be $enumerationObject.length
}
$singleCollection | Should -Be $enumerationObject.length
}
It "Should be able to treat a collection as a single object using the NoEnumerate switch" {
$singleCollection = $(Write-Output $enumerationObject -NoEnumerate | Measure-Object).Count
It "Should be able to treat a collection as a single object using the NoEnumerate switch" {
$singleCollection = $(Write-Output $enumerationObject -NoEnumerate | Measure-Object).Count
$singleCollection | Should -Be 1
}
$singleCollection | Should -Be 1
}
}
}