pester / Pester

Pester is the ubiquitous test and mock framework for PowerShell.
https://pester.dev/
Other
3.08k stars 470 forks source link

HaveParameter DefaultValue evaluates to '<empty>' when actual value is not empty #2285

Closed brianwest closed 1 year ago

brianwest commented 1 year ago

Checklist

What is the issue?

Should -HaveParameter -DefaultValue '' fails. Checking for an empty string, when the actual default value is something else, passes instead of failing too.

Expected Behavior

Should -HaveParameter -DefaultValue should be able to validate default values

Steps To Reproduce

Get-Command -Name Get-ChildItem | Should -HaveParameter -ParameterName 'Path' -DefaultValue '.'

Describe your environment

Pester version : 5.4.0 C:\Users\brwest\Documents\PowerShell\Modules\Pester\5.4.0\Pester.psm1 PowerShell version : 7.3.1 OS version : Microsoft Windows NT 10.0.22621.0

Possible Solution?

Get-ParameterInfo should leverage ASTs since v2 of PowerShell is no longer supported, according to https://pester.dev/docs/introduction/installation#compatibility. Current implementation requires that param block open parenthesis is on the same line as param keyword for $paramblock to have a count higher than one, which is for the new line, and is still not able to retrieve the default value, unless the parameter name is on the same line as the datatype.

fflaten commented 1 year ago

Thanks for the report! I agree this might be a good time to cleanup that v2 code. We actually use AST for this another place, so just a case of "if it ain't broke...". πŸ™‚

AST won't fix the repro though. It fails because Get-ChildItem is a binary cmdlet and DefaultValue isn't exposed in any way for those AFAIK (tips are welcome if possible). We should add a "-DefaultValue is not compatible with binary cmdlet" warning and ignore it in those cases.

brianwest commented 1 year ago

Maybe I should have provided a better example. I noticed the issue testing one of my own functions. I found that reformatting to have the open paren on the same line as param and putting the parameter name on the same line as the datatype does fix the issue. However, the result shouldn't depend on the format. I've also added code to my test to use an AST of the function's scriptblock and extract the ParamBlockAst and I'm able to validate all of the properties, regardless of the format. This would be my first one, but I'd like to submit the PR for the fix too, if that's alright.

fflaten commented 1 year ago

Aha, so we have two separate issues then. πŸ˜„ Will move my last comment to a new issue so we don't forget it.

If you have another repro for this issue, that would be great. Both as documentation here and as a test in the PR to avoid breaking it again later.

This would be my first one, but I'd like to submit the PR for the fix too, if that's alright.

Yes please, PRs are always appreciated. See CONTRIBUTING and let me know if you have any questions.

brianwest commented 1 year ago

Here's a better example:

function Test-Parameter {
    param
    (
        [Parameter()]
        [string]
        $Name = 'test'
    )
}

Get-Command -Name 'Test-Parameter' | Should -HaveParameter -ParameterName 'Name' -DefaultValue 'test'

InvalidResult: Expected command Test-Parameter to have a parameter Name, the default value to be 'test', but the default value was <empty>.

I am having difficulty building Pester. I've installed the 6.0.405 SDK, as well as the .NET Framework 4.5.2 Developer Pack, but I'm getting the following errors, when running .\build.ps1 -Clean from the root of the repository:

  Determining projects to restore...
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'Microsoft.NET.Test.Sdk (>= 17.3.2)' for 'net6.0'. [C:\Users\brwest\git\github\Pester\src\csharp\Pester.sln]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'NETStandard.Library (>= 2.0.3)' for '.NETStandard,Version=v2.0'. [C:\Users\brwest\git\github\Pester\src\csharp\Pester.sln]
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'xunit (>= 2.4.2)' for 'net6.0'. [C:\Users\brwest\git\github\Pester\src\csharp\Pester.sln]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'System.Management.Automation (>= 6.0.4)' for '.NETStandard,Version=v2.0'. [C:\Users\brwest\git\github\Pester\src\csharp\Pester.sln]
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'xunit.runner.visualstudio (>= 2.4.5)' for 'net6.0'. [C:\Users\brwest\git\github\Pester\src\csharp\Pester.sln]
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'coverlet.collector (>= 3.1.2)' for 'net6.0'. [C:\Users\brwest\git\github\Pester\src\csharp\Pester.sln]
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'System.Management.Automation (>= 6.0.4)' for 'net6.0'. [C:\Users\brwest\git\github\Pester\src\csharp\Pester.sln]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'Microsoft.PowerShell.3.ReferenceAssemblies (>= 1.0.0)' for '.NETFramework,Version=v4.5.2'. [C:\Users\brwest\git\github\Pester\src\csharp\Pester.sln]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'Microsoft.NETFramework.ReferenceAssemblies (>= 1.0.0)' for '.NETFramework,Version=v4.5.2'. [C:\Users\brwest\git\github\Pester\src\csharp\Pester.sln]
  Failed to restore C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj (in 114 ms).
  Failed to restore C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj (in 114 ms).
MSBuild version 17.4.1+9a89d02ff for .NET
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'Microsoft.NET.Test.Sdk (>= 17.3.2)' for 'net6.0'.
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'xunit (>= 2.4.2)' for 'net6.0'.
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'xunit.runner.visualstudio (>= 2.4.5)' for 'net6.0'.
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'coverlet.collector (>= 3.1.2)' for 'net6.0'.
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'System.Management.Automation (>= 6.0.4)' for 'net6.0'.
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'NETStandard.Library (>= 2.0.3)' for '.NETStandard,Version=v2.0'. [TargetFramework=net452]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'System.Management.Automation (>= 6.0.4)' for '.NETStandard,Version=v2.0'. [TargetFramework=net452]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'Microsoft.PowerShell.3.ReferenceAssemblies (>= 1.0.0)' for '.NETFramework,Version=v4.5.2'. [TargetFramework=net452]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'Microsoft.NETFramework.ReferenceAssemblies (>= 1.0.0)' for '.NETFramework,Version=v4.5.2'. [TargetFramework=net452]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'NETStandard.Library (>= 2.0.3)' for '.NETStandard,Version=v2.0'. [TargetFramework=netstandard2.0]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'System.Management.Automation (>= 6.0.4)' for '.NETStandard,Version=v2.0'. [TargetFramework=netstandard2.0]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'Microsoft.PowerShell.3.ReferenceAssemblies (>= 1.0.0)' for '.NETFramework,Version=v4.5.2'. [TargetFramework=netstandard2.0]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'Microsoft.NETFramework.ReferenceAssemblies (>= 1.0.0)' for '.NETFramework,Version=v4.5.2'. [TargetFramework=netstandard2.0]

Build FAILED.

C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'Microsoft.NET.Test.Sdk (>= 17.3.2)' for 'net6.0'.
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'xunit (>= 2.4.2)' for 'net6.0'.
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'xunit.runner.visualstudio (>= 2.4.5)' for 'net6.0'.
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'coverlet.collector (>= 3.1.2)' for 'net6.0'.
C:\Users\brwest\git\github\Pester\src\csharp\PesterTests\PesterTests.csproj : error NU1100: Unable to resolve 'System.Management.Automation (>= 6.0.4)' for 'net6.0'.
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'NETStandard.Library (>= 2.0.3)' for '.NETStandard,Version=v2.0'. [TargetFramework=net452]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'System.Management.Automation (>= 6.0.4)' for '.NETStandard,Version=v2.0'. [TargetFramework=net452]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'Microsoft.PowerShell.3.ReferenceAssemblies (>= 1.0.0)' for '.NETFramework,Version=v4.5.2'. [TargetFramework=net452]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'Microsoft.NETFramework.ReferenceAssemblies (>= 1.0.0)' for '.NETFramework,Version=v4.5.2'. [TargetFramework=net452]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'NETStandard.Library (>= 2.0.3)' for '.NETStandard,Version=v2.0'. [TargetFramework=netstandard2.0]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'System.Management.Automation (>= 6.0.4)' for '.NETStandard,Version=v2.0'. [TargetFramework=netstandard2.0]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'Microsoft.PowerShell.3.ReferenceAssemblies (>= 1.0.0)' for '.NETFramework,Version=v4.5.2'. [TargetFramework=netstandard2.0]
C:\Users\brwest\git\github\Pester\src\csharp\Pester\Pester.csproj : error NU1100: Unable to resolve 'Microsoft.NETFramework.ReferenceAssemblies (>= 1.0.0)' for '.NETFramework,Version=v4.5.2'. [TargetFramework=netstandard2.0]
    0 Warning(s)
    13 Error(s)

Time Elapsed 00:00:00.55
Exception: C:\Users\brwest\git\github\Pester\build.ps1:83
Line |
  83 |          throw "build failed!"
     |          ~~~~~~~~~~~~~~~~~~~~~
     | build failed!  

Here's the output from running winget list --name .net:

Microsoft .NET SDK 6.0.405 (x64)                          Microsoft.DotNet.SDK.6                 6.0.405   winget
Microsoft .NET Framework 4.5.2 Multi-Targeting Pack       {19E8AE59-4D4A-3534-B567-6CC08FA4102E} 4.5.51651
Microsoft .NET Framework 4.5.2 Multi-Targeting Pack (ENU) {290FC320-2F5A-329E-8840-C4193BD7A9EE} 4.5.51209
Microsoft .NET SDK 7.0.102 (x64)                          Microsoft.DotNet.SDK.7                 7.0.102   winget
Microsoft .NET Framework 4.8.1 Targeting Pack             {94DDB521-CDD4-4A83-BBE0-D3C856FE9420} 4.8.09032
Microsoft .NET Runtime - 6.0.13 (x64)                     Microsoft.DotNet.Runtime.6             6.0.13    winget
Microsoft .NET Framework 4.8.1 SDK                        {BD4C49AC-2A45-48B0-B3F7-0C6043987AD0} 4.8.09032
Microsoft Windows Desktop Runtime - 7.0.2 (x64)           Microsoft.DotNet.DesktopRuntime.7      7.0.2     winget

I've tried running without the .NET 7 SDK since neither https://github.com/pester/Pester/blob/main/CONTRIBUTING.md#required-software or 'src\csharp\Pester\Pester.csproj' mention it, but that results in:

Found .NET SDK, but did not find dotnet.dll at [C:\Program Files\dotnet\sdk\7.0.102\dotnet.dll]
Found .NET SDK, but did not find dotnet.dll at [C:\Program Files\dotnet\sdk\7.0.102\dotnet.dll]
Exception: C:\Users\brwest\git\github\Pester\build.ps1:83
Line |
  83 |          throw "build failed!"
     |          ~~~~~~~~~~~~~~~~~~~~~
     | build failed!

I assume I'm doing something wrong, but since I'm not a C# developer, I'm not sure what it is. Any help would be greatly appreciated.

fflaten commented 1 year ago

Thanks for the repro πŸ‘

We use .NET 6 and it should work. Do you get the default NuGet-feed if your run the command below? Just in case it's missing, blocked or overridden by a local nuget feed etc.?

PS /workspaces/Pester> dotnet nuget list source                                        
Registered Sources:
  1.  nuget.org [Enabled]
      https://api.nuget.org/v3/index.json

You can try the included devcontainer locally or through Github Codespace if you like.

brianwest commented 1 year ago

Adding nuget.org did the trick. Thanks, Frode!