-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use C# wrapper objects for PowerShell cmdlet output #2871
Conversation
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
src/PowerShell/Microsoft.WinGet.Client/PSObjects/FoundCatalogPackage.cs
Outdated
Show resolved
Hide resolved
} | ||
|
||
/// <summary> | ||
/// Gets the source of the catalog package. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Maybe add that it's the source name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to suggested.
} | ||
|
||
/// <summary> | ||
/// Gets the correlation data of the install result. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this correlation data, and what format does the string have?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm honestly not sure, I even tried installing a package and manually failing it, but no output. I removed it entirely and if people want it back, I can add it again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correlation data is passed in from caller for their own correlation purposes. We return it so caller can correlate to their operations
/// <summary> | ||
/// CatalogPackage wrapper object for displaying to PowerShell. | ||
/// </summary> | ||
public class InstalledCatalogPackage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the difference between FoundCatalogPackage
and InstalledCatalogPackage
? Is it about which cmdlets they can be used in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only difference is whether we use InstalledVersion or DefaultInstallVersion to obtain the Version that we display to the user. I created a parent class called CatalogPackage
that FoundCatalogPackage
and InstalledCatalogPackage
inherit from so that there less repeated properties.
$package.Name | Should -Be 'TestExeInstaller' | ||
$package.Id | Should -Be 'AppInstallerTest.TestExeInstaller' | ||
$package.Version | Should -Be '2.0.0.0' | ||
$package.Source | Should -Be 'TestSource' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if there is a way to do this all in one command. Something like
$package | Should -Be @{
Name: 'TestExeInstaller'
Id: 'AppInstallerTest.TestExeInstaller'
}
I have never used Pester and I don't know enough PS, so I genuinely don't know if something like that is possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this and it didn't work. Also the documentation doesn't have anything like this so I will leave it as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You would just need to do something like:
Function MatchesObject($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because){
$succeeded = $true
$failMessage = ''
foreach ($key in $ExpectedValue.Keys){
if ($ActualValue.Keys -contains $key){
if ($ActualValue[$key] -ceq $ExpectedValue[$key]){
} else {
$succeeded = $false
$failMessage = "Failed to validate $key. Actual: $($ActualValue[$key]); Expected: $($ExpectedValue[$key])"
}
} else {
$succeeded = $false
$failMessage = "Failed to validate $key. Value not present in object"
}
}
if ($Negate) {
$succeeded = !$succeeded
}
return New-Object psobject -Property @{
Succeeded = $succeeded
FailureMessage = $failMessage
}
}
Add-ShouldOperator -Name MatchObject -Test $function:MatchesObject -Alias MO
Then you could do
$package | Should -MatchObject @{ Name: 'TestExeInstaller' Id: 'AppInstallerTest.TestExeInstaller' }
src/PowerShell/tests/Setup.Tests.ps1
Outdated
Setup file for all Pester tests related to the Microsoft.WinGet.Client PowerShell module. | ||
#> | ||
|
||
BeforeAll { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I imagine there's Pester magic that makes this run before all tests? Is it possible to add a cleanup step to always uninstall the installed tests apps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added an AfterAll step that cleans up the installed test packages and sources that were added during the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like AfterAll is executed once after all the tests. Could we want to uninstall the packages after each tests?
$package.Name | Should -Be 'TestExeInstaller' | ||
$package.Id | Should -Be 'AppInstallerTest.TestExeInstaller' | ||
$package.Version | Should -Be '2.0.0.0' | ||
$package.Source | Should -Be 'TestSource' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You would just need to do something like:
Function MatchesObject($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because){
$succeeded = $true
$failMessage = ''
foreach ($key in $ExpectedValue.Keys){
if ($ActualValue.Keys -contains $key){
if ($ActualValue[$key] -ceq $ExpectedValue[$key]){
} else {
$succeeded = $false
$failMessage = "Failed to validate $key. Actual: $($ActualValue[$key]); Expected: $($ExpectedValue[$key])"
}
} else {
$succeeded = $false
$failMessage = "Failed to validate $key. Value not present in object"
}
}
if ($Negate) {
$succeeded = !$succeeded
}
return New-Object psobject -Property @{
Succeeded = $succeeded
FailureMessage = $failMessage
}
}
Add-ShouldOperator -Name MatchObject -Test $function:MatchesObject -Alias MO
Then you could do
$package | Should -MatchObject @{ Name: 'TestExeInstaller' Id: 'AppInstallerTest.TestExeInstaller' }
It 'Find by Name sort by Version' { | ||
$package = Find-WinGetPackage -Source 'TestSource' -Name 'TestPortableExe' | Sort-Object 'Version' | ||
$package[0].Name | Should -Be 'TestPortableExeWithCommand' | ||
$package[1].Name | Should -Be 'TestPortableExe' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is Pester set up to collect all failures? If not, I think it should be
https://pester.dev/docs/assertions/should-command#collect-all-should-failures
src/PowerShell/Microsoft.WinGet.Client/PSObjects/CatalogPackage.cs
Outdated
Show resolved
Hide resolved
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
Related to: #2796
Currently, the PowerShell module outputs a COM object which, based on feedback from the community, is not easily usable and also causes issues with certain behaviors such as getting properties and sorting by specific fields (id, version, etc.). This change fixes those issues by using a better formatted C# wrapper object around the data from the COM object and outputs that to PowerShell.
Tests:
I added basic Pester tests but did not include them in the pipeline as the module looks for the wingetdev package to be installed on the build machine (specifically executing WindowsPackageManagerServer.exe) before creating any COM instances. I will work on that in a separate PR but I have included the basic tests here which can be run locally while having the localhost webserver running. Since we already have basic E2E test coverage for the module, it is not absolutely necessary right now.
Microsoft Reviewers: Open in CodeFlow