mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-17 12:45:47 +00:00
Make Select-Object/ForEach-Object/Where-Object see dynamic properties (#6898)
Dynamic (DLR) objects work in some places today, but not others. This change expands that support to ForEach-Object, Where-Object and the family of cmdlets that use 'MshExpression' (Select-Object, etc.).
This change addresses both wildcard and non-wildcard cases. In wildcard cases, it uses the existing support of generating PSDynamicMember objects for names returned by GetDynamicMemberNames.
In non-wildcard cases, a dynamic property access is attempted whether or not the name shows up in GetDynamicMemberNames, but a truly "blind" access is only attempted if we see that the base object is an IDMOP. If the dynamic access fails, you'll get the same or a similar error experience as before ("The property 'Blarg' cannot be found", or no error at all, depending on the cmdlet and the strict mode setting).
The included test coverage includes a stub for the.ForEach operator--once people are happy with this change, I can continue by adding support there.
This change should allegedly also have positive perf impact, though in actual perf testing, although it does seem ever-so-slightly faster, I found it difficult to measure much difference at all.
This commit is contained in:
1 parent
3a5a3e4c6e
commit
ce3cb68551
7 files changed
+415
-89
No files matched your search
@@ -1,6 +1,7 @@
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
. (Join-Path -Path $PSScriptRoot -ChildPath Test-Mocks.ps1)
|
||||
Add-TestDynamicType
|
||||
|
||||
Describe "Select-Object" -Tags "CI" {
|
||||
BeforeEach {
|
||||
@@ -242,6 +243,47 @@ Describe "Select-Object DRT basic functionality" -Tags "CI" {
|
||||
$results.Count | Should -Be 1
|
||||
$results[0] | Should -BeExactly "3"
|
||||
}
|
||||
|
||||
It "Select-Object should handle dynamic (DLR) properties"{
|
||||
$dynObj = [TestDynamic]::new()
|
||||
$results = $dynObj, $dynObj | Select-Object -ExpandProperty FooProp
|
||||
$results.Count | Should -Be 2
|
||||
$results[0] | Should -Be 123
|
||||
$results[1] | Should -Be 123
|
||||
}
|
||||
|
||||
It "Select-Object should handle dynamic (DLR) properties without GetDynamicMemberNames hint"{
|
||||
$dynObj = [TestDynamic]::new()
|
||||
$results = $dynObj, $dynObj | Select-Object -ExpandProperty HiddenProp
|
||||
$results.Count | Should -Be 2
|
||||
$results[0] | Should -Be 789
|
||||
$results[1] | Should -Be 789
|
||||
}
|
||||
|
||||
It "Select-Object should handle wildcarded dynamic (DLR) properties when hinted by GetDynamicMemberNames"{
|
||||
$dynObj = [TestDynamic]::new()
|
||||
$results = $dynObj, $dynObj | Select-Object -ExpandProperty FooP*
|
||||
$results.Count | Should -Be 2
|
||||
$results[0] | Should -Be 123
|
||||
$results[1] | Should -Be 123
|
||||
}
|
||||
|
||||
It "Select-Object should work when multiple dynamic (DLR) properties match"{
|
||||
$dynObj = [TestDynamic]::new()
|
||||
$results = $dynObj, $dynObj | Select-Object *Prop
|
||||
$results.Count | Should -Be 2
|
||||
$results[0].FooProp | Should -Be 123
|
||||
$results[0].BarProp | Should -Be 456
|
||||
$results[1].FooProp | Should -Be 123
|
||||
$results[1].BarProp | Should -Be 456
|
||||
}
|
||||
|
||||
It "Select-Object -ExpandProperty should yield errors if multiple dynamic (DLR) properties match"{
|
||||
$dynObj = [TestDynamic]::new()
|
||||
$e = { $results = $dynObj, $dynObj | Select-Object -ExpandProperty *Prop -ErrorAction Stop} |
|
||||
Should -Throw -PassThru -ErrorId "MutlipleExpandProperties,Microsoft.PowerShell.Commands.SelectObjectCommand"
|
||||
$e.CategoryInfo | Should -Match "PSArgumentException"
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Select-Object with Property = '*'" -Tags "CI" {
|
||||
|
||||
Reference in new issue
Block a user