Skip to content

Commit

Permalink
Merge branch 'main' into should-invoke
Browse files Browse the repository at this point in the history
  • Loading branch information
nohwnd committed Jan 17, 2025
2 parents 90a2494 + f49f842 commit 0fcb45f
Show file tree
Hide file tree
Showing 55 changed files with 1,434 additions and 567 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/backport.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ permissions:

jobs:
backport:
uses: dotnet/arcade/.github/workflows/backport-base.yml@main
uses: dotnet/arcade/.github/workflows/backport-base.yml@backport-just-author
with:
repository_owners: 'pester'
pr_title_template: '%source_pr_title% by @%source_pr_author% in #%source_pr_number% (backport to %target_branch%)'
2 changes: 2 additions & 0 deletions BACKERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@
@tabs-not-spaces
@avanreijn
@DevOpsCollectiveINC
@chocolatey

9 changes: 4 additions & 5 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ stages:
PS7_Ubuntu_22_04:
vmImage: ubuntu-22.04
pwsh: true
PS7_macOS_12:
vmImage: macOS-12
pwsh: true
PS7_macOS_13:
vmImage: macOS-13
pwsh: true
PS7_macOS_14:
vmImage: macOS-14
pwsh: true
PS7_Windows_Server2019:
vmImage: windows-2019
pwsh: true
Expand All @@ -114,9 +114,8 @@ stages:
script: |
& ./test.ps1 -CI -CC -PassThru -NoBuild
workingDirectory: '$(Build.SourcesDirectory)'
- task: PublishCodeCoverageResults@1
- task: PublishCodeCoverageResults@2
inputs:
codeCoverageTool: 'JaCoCo'
summaryFileLocation: 'coverage.xml'
pathToSources: '$(Build.SourcesDirectory)/bin/'
failIfCoverageEmpty: false
Expand Down
5 changes: 3 additions & 2 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ if ($Clean) {
if ($Clean) {
# Update PesterConfiguration help in about_PesterConfiguration
if ($PSVersionTable.PSVersion.Major -ge 6) {
$null = [Reflection.Assembly]::LoadFrom("$PSScriptRoot/src/csharp/Pester/bin/$Configuration/net6.0/Pester.dll")
$null = [Reflection.Assembly]::LoadFrom("$PSScriptRoot/src/csharp/Pester/bin/$Configuration/net8.0/Pester.dll")
}
else {
$null = [Reflection.Assembly]::LoadFrom("$PSScriptRoot/src/csharp/Pester/bin/$Configuration/net462/Pester.dll")
Expand Down Expand Up @@ -202,9 +202,10 @@ if ($Clean) {
, ("$PSScriptRoot/src/schemas/JUnit4/*.xsd", "$PSScriptRoot/bin/schemas/JUnit4/")
, ("$PSScriptRoot/src/schemas/NUnit25/*.xsd", "$PSScriptRoot/bin/schemas/NUnit25/")
, ("$PSScriptRoot/src/schemas/NUnit3/*.xsd", "$PSScriptRoot/bin/schemas/NUnit3/")
, ("$PSScriptRoot/src/schemas/Cobertura/*.dtd", "$PSScriptRoot/bin/schemas/Cobertura/")
, ("$PSScriptRoot/src/schemas/JaCoCo/*.dtd", "$PSScriptRoot/bin/schemas/JaCoCo/")
, ("$PSScriptRoot/src/csharp/Pester/bin/$Configuration/net462/Pester.dll", "$PSScriptRoot/bin/bin/net462/")
, ("$PSScriptRoot/src/csharp/Pester/bin/$Configuration/net6.0/Pester.dll", "$PSScriptRoot/bin/bin/net6.0/")
, ("$PSScriptRoot/src/csharp/Pester/bin/$Configuration/net8.0/Pester.dll", "$PSScriptRoot/bin/bin/net8.0/")
)
}

Expand Down
3 changes: 2 additions & 1 deletion publish/filesToPublish.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
'Pester.Format.ps1xml'
'PesterConfiguration.Format.ps1xml'
'bin/net462/Pester.dll'
'bin/net6.0/Pester.dll'
'bin/net8.0/Pester.dll'
'en-US/about_Pester.help.txt'
'en-US/about_PesterConfiguration.help.txt'
'schemas/Cobertura/coverage-loose.dtd'
'schemas/JaCoCo/report.dtd'
'schemas/JUnit4/junit_schema_4.xsd'
'schemas/NUnit25/nunit_schema_2.5.xsd'
Expand Down
4 changes: 4 additions & 0 deletions src/Main.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ function Add-ShouldOperator {
[switch] $SupportsArrayInput
)

Assert-BoundScriptBlockInput -ScriptBlock $Test

$entry = [PSCustomObject]@{
Test = $Test
SupportsArrayInput = [bool]$SupportsArrayInput
Expand Down Expand Up @@ -1260,6 +1262,8 @@ function BeforeDiscovery {
[ScriptBlock]$ScriptBlock
)

Assert-BoundScriptBlockInput -ScriptBlock $ScriptBlock

if ($ExecutionContext.SessionState.PSVariable.Get('invokedViaInvokePester')) {
if ($state.CurrentBlock.IsRoot -and -not $state.CurrentBlock.FrameworkData.MissingParametersProcessed) {
# For undefined parameters in container, add parameter's default value to Data
Expand Down
3 changes: 0 additions & 3 deletions src/Pester.RSpec.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,6 @@ function New-PesterConfiguration {
.LINK
https://pester.dev/docs/commands/Invoke-Pester
.LINK
about_PesterConfiguration
#>
[CmdletBinding()]
[OutputType([PesterConfiguration])]
Expand Down
21 changes: 21 additions & 0 deletions src/Pester.Runtime.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2474,6 +2474,10 @@ function New-BlockContainerObject {
default { throw [System.ArgumentOutOfRangeException]'' }
}

if ($item -is [scriptblock]) {
Assert-BoundScriptBlockInput -ScriptBlock $item
}

$c = [Pester.ContainerInfo]::Create()
$c.Type = $type
$c.Item = $item
Expand Down Expand Up @@ -2604,3 +2608,20 @@ function Add-MissingContainerParameters ($RootBlock, $Container, $CallingFunctio

$RootBlock.FrameworkData.MissingParametersProcessed = $true
}

function Assert-BoundScriptBlockInput {
param(
[Parameter(Mandatory = $true)]
[ScriptBlock] $ScriptBlock
)
$internalSessionState = $script:ScriptBlockSessionStateInternalProperty.GetValue($ScriptBlock, $null)
if ($null -eq $internalSessionState) {
$maxLength = 250
$prettySb = (Format-Nicely2 $ScriptBlock) -replace '\s{2,}', ' '
if ($prettySb.Length -gt $maxLength) {
$prettySb = "$($prettySb.Remove($maxLength))..."
}

throw [System.ArgumentException]::new("Unbound scriptblock is not allowed, because it would run inside of Pester session state and produce unexpected results. See https://github.com/pester/Pester/issues/2411 for more details and workarounds. ScriptBlock: '$prettySb'")
}
}
6 changes: 3 additions & 3 deletions src/Pester.Types.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ if ($null -ne $configurationType) {
}

if ($PSVersionTable.PSVersion.Major -ge 6) {
$path = "$PSScriptRoot/bin/net6.0/Pester.dll"
$path = "$PSScriptRoot/bin/net8.0/Pester.dll"
# PESTER_BUILD
if ((Get-Variable -Name "PESTER_BUILD" -ValueOnly -ErrorAction Ignore)) {
$path = "$PSScriptRoot/../bin/bin/net6.0/Pester.dll"
$path = "$PSScriptRoot/../bin/bin/net8.0/Pester.dll"
}
else {
$path = "$PSScriptRoot/../bin/bin/net6.0/Pester.dll"
$path = "$PSScriptRoot/../bin/bin/net8.0/Pester.dll"
}
# end PESTER_BUILD
& $SafeCommands['Add-Type'] -Path $path
Expand Down
4 changes: 2 additions & 2 deletions src/Pester.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,10 @@
LicenseUri = "https://www.apache.org/licenses/LICENSE-2.0.html"

# Release notes for this particular version of the module
ReleaseNotes = 'https://github.com/pester/Pester/releases/tag/6.0.0-alpha4'
ReleaseNotes = 'https://github.com/pester/Pester/releases/tag/6.0.0-alpha5'

# Prerelease string of this module
Prerelease = 'alpha4'
Prerelease = 'alpha5'
}

# Minimum assembly version required
Expand Down
2 changes: 1 addition & 1 deletion src/csharp/Pester/CodeCoverageConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static CodeCoverageConfiguration ShallowClone(CodeCoverageConfiguration c
public CodeCoverageConfiguration() : base("Options to enable and configure Pester's code coverage feature.")
{
Enabled = new BoolOption("Enable CodeCoverage.", false);
OutputFormat = new StringOption("Format to use for code coverage report. Possible values: JaCoCo, CoverageGutters", "JaCoCo");
OutputFormat = new StringOption("Format to use for code coverage report. Possible values: JaCoCo, CoverageGutters, Cobertura", "JaCoCo");
OutputPath = new StringOption("Path relative to the current directory where code coverage report is saved.", "coverage.xml");
OutputEncoding = new StringOption("Encoding of the output file.", "UTF8");
Path = new StringArrayOption("Directories or files to be used for code coverage, by default the Path(s) from general settings are used, unless overridden here.", new string[0]);
Expand Down
80 changes: 80 additions & 0 deletions src/csharp/Pester/CoverageLocationVisitor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation.Language;

namespace Pester
{
/// <summary>
/// A visitor class for traversing the PowerShell AST to collect coverage-relevant locations.
/// This replaces predicate-based filtering with a centralized, extensible approach.
///
/// Advantages:
/// - Efficiently skips nodes with attributes like [ExcludeFromCodeCoverage].
/// - Simplifies logic by handling each AST type in dedicated methods.
/// </summary>
public class CoverageLocationVisitor : AstVisitor2
{
public readonly List<Ast> CoverageLocations = new();

public override AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst)
{
if (scriptBlockAst.ParamBlock?.Attributes != null)
{
foreach (var attribute in scriptBlockAst.ParamBlock.Attributes)
{
if (attribute.TypeName.GetReflectionType() == typeof(ExcludeFromCodeCoverageAttribute))
{
return AstVisitAction.SkipChildren;
}
}
}
return AstVisitAction.Continue;
}

public override AstVisitAction VisitCommand(CommandAst commandAst)
{
CoverageLocations.Add(commandAst);
return AstVisitAction.Continue;
}

public override AstVisitAction VisitCommandExpression(CommandExpressionAst commandExpressionAst)
{
CoverageLocations.Add(commandExpressionAst);
return AstVisitAction.Continue;
}

public override AstVisitAction VisitDynamicKeywordStatement(DynamicKeywordStatementAst dynamicKeywordStatementAst)
{
CoverageLocations.Add(dynamicKeywordStatementAst);
return AstVisitAction.Continue;
}

public override AstVisitAction VisitBreakStatement(BreakStatementAst breakStatementAst)
{
CoverageLocations.Add(breakStatementAst);
return AstVisitAction.Continue;
}

public override AstVisitAction VisitContinueStatement(ContinueStatementAst continueStatementAst)
{
CoverageLocations.Add(continueStatementAst);
return AstVisitAction.Continue;
}

public override AstVisitAction VisitExitStatement(ExitStatementAst exitStatementAst)
{
CoverageLocations.Add(exitStatementAst);
return AstVisitAction.Continue;
}

public override AstVisitAction VisitThrowStatement(ThrowStatementAst throwStatementAst)
{
CoverageLocations.Add(throwStatementAst);
return AstVisitAction.Continue;
}

// ReturnStatementAst is excluded as it's not behaving consistent.
// "return" is not hit in 5.1 but fixed in a later version. Using "return 123" we get hit on 123 but not return.
// See https://github.com/pester/Pester/issues/1465#issuecomment-604323645
}
}
14 changes: 5 additions & 9 deletions src/csharp/Pester/Pester.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net462</TargetFrameworks>
<TargetFrameworks>net8.0;net462</TargetFrameworks>
<LangVersion>latest</LangVersion>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<DebugType>embedded</DebugType>
Expand All @@ -11,14 +11,10 @@
<DefineConstants>$(DefineConstants);PESTER</DefineConstants>
</PropertyGroup>

<!-- PowerShell 7.2.x is the oldest supported PowerShell version. That version is built using net6.0.
But there is a bug in 7.2.0 reference assemblies, up to 7.2.10, where the IExtens.File is missing from the reference assembly:
https://github.com/PowerShell/PowerShell/issues/16408
So we use the version released before 7.2.0 which was 7.1.7. We could probably use 7.2.10 safely as well,
-->
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="System.Management.Automation" Version="7.1.7" />
<!-- PowerShell 7.4.x is the oldest supported PowerShell version. That version is built using net8.0. -->
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<!-- Versions older than 7.4.6 have security vulnerabilities. -->
<PackageReference Include="System.Management.Automation" Version="7.4.6" />
</ItemGroup>

<!-- Windows PowerShell 5.1 is the only Windows PowerShell that is still in support, and it is built using .NET Framework 4.5.2.
Expand Down
Loading

0 comments on commit 0fcb45f

Please sign in to comment.