From fa4d22c381a0191ca11ec3306c7767fd164e42c8 Mon Sep 17 00:00:00 2001 From: Staffan Gustafsson Date: Wed, 8 Aug 2018 19:03:03 +0200 Subject: [PATCH 1/4] Adding SkipIndex parameter to Select-Object --- .../commands/utility/select-object.cs | 95 +++++++++++++++---- .../Select-Object.Tests.ps1 | 12 +++ 2 files changed, 90 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs index 4b31897411c..951a3d94bd4 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs @@ -177,11 +177,33 @@ public int[] Index { _index = value; _indexSpecified = true; + _isIncludeIndex = true; Array.Sort(_index); } } + + /// + /// Used to display all objects not at specified index. + /// + /// + [Parameter(ParameterSetName = "SkipIndexParameter")] + [ValidateRangeAttribute(0, int.MaxValue)] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public int[] SkipIndex { + get { + return _index; + } + set { + _index = value; + _indexSpecified = true; + _isIncludeIndex = false; + Array.Sort(_index); + } + } + private int[] _index; private bool _indexSpecified; + private bool _isIncludeIndex; #endregion @@ -641,15 +663,18 @@ protected override void BeginProcessing() _selectObjectQueue = new SelectObjectQueue(_first, _last, Skip, SkipLast, _firstOrLastSpecified); } - private int _indexOfCurrentObject = 0; - private int _indexCount = 0; /// + /// Handles processing of InputObject. /// protected override void ProcessRecord() { if (InputObject != AutomationNull.Value && InputObject != null) { - if (!_indexSpecified) + if (_indexSpecified) + { + ProcessIndexed(); + } + else { _selectObjectQueue.Enqueue(InputObject); PSObject streamingInputObject = _selectObjectQueue.StreamingDequeue(); @@ -657,39 +682,75 @@ protected override void ProcessRecord() { ProcessObjectAndHandleErrors(streamingInputObject); } + if (_selectObjectQueue.AllRequestedObjectsProcessed && !this.Wait) { this.EndProcessing(); throw new StopUpstreamCommandsException(this); } } - else + } + } + + private int _indexOfCurrentObject; + private int _indexCount; + + /// + /// Handles processing of InputObject if -Index or -SkipIndex is specified. + /// + private void ProcessIndexed() + { + if (_isIncludeIndex) + { + if (_indexOfCurrentObject < _index.Length) { - if (_indexOfCurrentObject < _index.Length) + int currentlyRequestedIndex = _index[_indexOfCurrentObject]; + if (_indexCount == currentlyRequestedIndex) { - int currentlyRequestedIndex = _index[_indexOfCurrentObject]; - if (_indexCount == currentlyRequestedIndex) + ProcessObjectAndHandleErrors(InputObject); + while ((_indexOfCurrentObject < _index.Length) && (_index[_indexOfCurrentObject] == currentlyRequestedIndex)) { - ProcessObjectAndHandleErrors(InputObject); - while ((_indexOfCurrentObject < _index.Length) && (_index[_indexOfCurrentObject] == currentlyRequestedIndex)) - { - _indexOfCurrentObject++; - } + _indexOfCurrentObject++; } } + } + + if (!Wait && _indexOfCurrentObject >= _index.Length) + { + EndProcessing(); + throw new StopUpstreamCommandsException(this); + } - if (!this.Wait && _indexOfCurrentObject >= _index.Length) + _indexCount++; + } + else + { + if (_indexOfCurrentObject < _index.Length) + { + int nextIndexToSkip = _index[_indexOfCurrentObject]; + if (_indexCount != nextIndexToSkip) { - this.EndProcessing(); - throw new StopUpstreamCommandsException(this); + ProcessObjectAndHandleErrors(InputObject); } - - _indexCount++; + else + { + while ((_indexOfCurrentObject < _index.Length) && (_index[_indexOfCurrentObject] == nextIndexToSkip)) + { + _indexOfCurrentObject++; + } + } + } + else + { + ProcessObjectAndHandleErrors(InputObject); } + + _indexCount++; } } /// + /// Completes the processing of Input. /// protected override void EndProcessing() { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 index 8565b3ccaef..f9eb9ec48d6 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 @@ -244,6 +244,18 @@ Describe "Select-Object DRT basic functionality" -Tags "CI" { $results[0] | Should -BeExactly "3" } + It "Select-Object with SkipIndex should work" { + $results = "1", "2", "3" | Select-Object -SkipIndex 0, 2 + $results.Count | Should -Be 1 + $results[0] | Should -BeExactly "2" + } + + It "Select-Object with SkipIndex should work with index out of range" { + $results = 0..10 | Select-Object -SkipIndex 5, 6, 7, 8, 11 + $results.Count | Should -Be 7 + $results -join ',' | Should -BeExactly "0,1,2,3,4,9,10" + } + It "Select-Object should handle dynamic (DLR) properties"{ $dynObj = [TestDynamic]::new() $results = $dynObj, $dynObj | Select-Object -ExpandProperty FooProp From 4acbfe92f77d82092b022c1e7404c2b85ec23196 Mon Sep 17 00:00:00 2001 From: Staffan Gustafsson Date: Wed, 8 Aug 2018 19:52:41 +0200 Subject: [PATCH 2/4] CodeFactor issues --- .../commands/utility/select-object.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs index 951a3d94bd4..7f09775d423 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs @@ -189,11 +189,14 @@ public int[] Index [Parameter(ParameterSetName = "SkipIndexParameter")] [ValidateRangeAttribute(0, int.MaxValue)] [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public int[] SkipIndex { - get { + public int[] SkipIndex + { + get + { return _index; } - set { + set + { _index = value; _indexSpecified = true; _isIncludeIndex = false; From 2383918c2bc7485ea8c9153ddf2ee9ce243c7a8c Mon Sep 17 00:00:00 2001 From: Staffan Gustafsson Date: Thu, 9 Aug 2018 00:28:00 +0200 Subject: [PATCH 3/4] Addressing dantraMSFT review comments. --- .../commands/utility/select-object.cs | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs index 7f09775d423..aece2f1466d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs @@ -161,7 +161,7 @@ public int First public SwitchParameter Wait { get; set; } /// - /// Used to display the object at specified index. + /// Used to display the object at the specified index. /// /// [Parameter(ParameterSetName = "IndexParameter")] @@ -183,7 +183,7 @@ public int[] Index } /// - /// Used to display all objects not at specified index. + /// Used to display all objects at the specified indices. /// /// [Parameter(ParameterSetName = "SkipIndexParameter")] @@ -695,8 +695,15 @@ protected override void ProcessRecord() } } - private int _indexOfCurrentObject; - private int _indexCount; + /// + /// The index of the active index filter. + /// + private int _currentFilterIndex; + + /// + /// The index of the object being processed. + /// + private int _currentObjectIndex; /// /// Handles processing of InputObject if -Index or -SkipIndex is specified. @@ -705,41 +712,41 @@ private void ProcessIndexed() { if (_isIncludeIndex) { - if (_indexOfCurrentObject < _index.Length) + if (_currentFilterIndex < _index.Length) { - int currentlyRequestedIndex = _index[_indexOfCurrentObject]; - if (_indexCount == currentlyRequestedIndex) + int nextIndexToOutput = _index[_currentFilterIndex]; + if (_currentObjectIndex == nextIndexToOutput) { ProcessObjectAndHandleErrors(InputObject); - while ((_indexOfCurrentObject < _index.Length) && (_index[_indexOfCurrentObject] == currentlyRequestedIndex)) + while ((_currentFilterIndex < _index.Length) && (_index[_currentFilterIndex] == nextIndexToOutput)) { - _indexOfCurrentObject++; + _currentFilterIndex++; } } } - if (!Wait && _indexOfCurrentObject >= _index.Length) + if (!Wait && _currentFilterIndex >= _index.Length) { EndProcessing(); throw new StopUpstreamCommandsException(this); } - _indexCount++; + _currentObjectIndex++; } else { - if (_indexOfCurrentObject < _index.Length) + if (_currentFilterIndex < _index.Length) { - int nextIndexToSkip = _index[_indexOfCurrentObject]; - if (_indexCount != nextIndexToSkip) + int nextIndexToSkip = _index[_currentFilterIndex]; + if (_currentObjectIndex != nextIndexToSkip) { ProcessObjectAndHandleErrors(InputObject); } else { - while ((_indexOfCurrentObject < _index.Length) && (_index[_indexOfCurrentObject] == nextIndexToSkip)) + while ((_currentFilterIndex < _index.Length) && (_index[_currentFilterIndex] == nextIndexToSkip)) { - _indexOfCurrentObject++; + _currentFilterIndex++; } } } @@ -748,7 +755,7 @@ private void ProcessIndexed() ProcessObjectAndHandleErrors(InputObject); } - _indexCount++; + _currentObjectIndex++; } } From 2ef9869aae2a601e20f84eb4d96fdd5b29e5731e Mon Sep 17 00:00:00 2001 From: Staffan Gustafsson Date: Thu, 9 Aug 2018 08:11:00 +0200 Subject: [PATCH 4/4] Use -HaveCount in tests. --- .../Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 index f9eb9ec48d6..872b7850497 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 @@ -246,13 +246,13 @@ Describe "Select-Object DRT basic functionality" -Tags "CI" { It "Select-Object with SkipIndex should work" { $results = "1", "2", "3" | Select-Object -SkipIndex 0, 2 - $results.Count | Should -Be 1 + $results | Should -HaveCount 1 $results[0] | Should -BeExactly "2" } It "Select-Object with SkipIndex should work with index out of range" { $results = 0..10 | Select-Object -SkipIndex 5, 6, 7, 8, 11 - $results.Count | Should -Be 7 + $results | Should -HaveCount 7 $results -join ',' | Should -BeExactly "0,1,2,3,4,9,10" }