Skip to content

Commit bffc7ae

Browse files
Merge pull request #1513 from PowerShell/andschwa/import-pester-stub
Import `InvokePesterStub.ps1` from `vscode-powershell` (with history)
2 parents 1d23364 + b5be708 commit bffc7ae

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
#!/usr/bin/env pwsh
2+
3+
<#
4+
.SYNOPSIS
5+
Stub around Invoke-Pester command used by VSCode PowerShell extension.
6+
.DESCRIPTION
7+
The stub checks the version of Pester and if >= 4.6.0, invokes Pester
8+
using the LineNumber parameter (if specified). Otherwise, it invokes
9+
using the TestName parameter (if specified). If the All parameter
10+
is specified, then all the tests are invoked in the specifed file.
11+
Finally, if none of these three parameters are specified, all tests
12+
are invoked and a warning is issued indicating what the user can do
13+
to allow invocation of individual Describe blocks.
14+
.EXAMPLE
15+
PS C:\> .\InvokePesterStub.ps1 ~\project\test\foo.tests.ps1 -LineNumber 14
16+
Invokes a specific test by line number in the specified file.
17+
.EXAMPLE
18+
PS C:\> .\InvokePesterStub.ps1 ~\project\test\foo.tests.ps1 -TestName 'Foo Tests'
19+
Invokes a specific test by test name in the specified file.
20+
.EXAMPLE
21+
PS C:\> .\InvokePesterStub.ps1 ~\project\test\foo.tests.ps1 -All
22+
Invokes all tests in the specified file.
23+
.INPUTS
24+
None
25+
.OUTPUTS
26+
None
27+
#>
28+
param(
29+
# Specifies the path to the test script.
30+
[Parameter(Position=0, Mandatory)]
31+
[ValidateNotNullOrEmpty()]
32+
[string]
33+
$ScriptPath,
34+
35+
# Specifies the name of the test taken from the Describe block's name.
36+
[Parameter()]
37+
[string]
38+
$TestName,
39+
40+
# Specifies the starting line number of the DescribeBlock. This feature requires
41+
# Pester 4.6.0 or higher.
42+
[Parameter()]
43+
[ValidatePattern('\d*')]
44+
[string]
45+
$LineNumber,
46+
47+
# If specified, executes all the tests in the specified test script.
48+
[Parameter()]
49+
[switch]
50+
$All,
51+
52+
[Parameter()]
53+
[switch] $MinimumVersion5,
54+
55+
[Parameter(Mandatory)]
56+
[string] $Output,
57+
58+
[Parameter()]
59+
[string] $OutputPath
60+
)
61+
62+
$pesterModule = Microsoft.PowerShell.Core\Get-Module Pester
63+
# add one line, so the subsequent output is not shifted to the side
64+
Write-Output ''
65+
66+
if (!$pesterModule) {
67+
Write-Output "Importing Pester module..."
68+
if ($MinimumVersion5) {
69+
$pesterModule = Microsoft.PowerShell.Core\Import-Module Pester -ErrorAction Ignore -PassThru -MinimumVersion 5.0.0
70+
}
71+
72+
if (!$pesterModule) {
73+
$pesterModule = Microsoft.PowerShell.Core\Import-Module Pester -ErrorAction Ignore -PassThru
74+
}
75+
76+
if (!$pesterModule) {
77+
Write-Warning "Failed to import Pester. You must install Pester module to run or debug Pester tests."
78+
Write-Warning "$(if ($MinimumVersion5) {"Recommended version to install is Pester 5.0.0 or newer. "})You can install Pester by executing: Install-Module Pester$(if ($MinimumVersion5) {" -MinimumVersion 5.0.0" }) -Scope CurrentUser -Force"
79+
return
80+
}
81+
}
82+
83+
$pester4Output = switch ($Output) {
84+
"None" { "None" }
85+
"Minimal" { "Fails" }
86+
default { "All" }
87+
}
88+
89+
if ($MinimumVersion5 -and $pesterModule.Version -lt "5.0.0") {
90+
Write-Warning "Pester 5.0.0 or newer is required because setting PowerShell > Pester: Use Legacy Code Lens is disabled, but Pester $($pesterModule.Version) is loaded. Some of the code lens features might not work as expected."
91+
}
92+
93+
94+
function Get-InvokePesterParams {
95+
$invokePesterParams = @{
96+
Script = $ScriptPath
97+
}
98+
99+
if ($pesterModule.Version -ge '3.4.0') {
100+
# -PesterOption was introduced before 3.4.0, and VSCodeMarker in 4.0.3-rc,
101+
# but because no-one checks the integrity of this hashtable we can call
102+
# all of the versions down to 3.4.0 like this
103+
$invokePesterParams.Add("PesterOption", @{ IncludeVSCodeMarker = $true })
104+
}
105+
106+
if ($pesterModule.Version -ge '3.4.5') {
107+
# -Show was introduced in 3.4.5
108+
$invokePesterParams.Add("Show", $pester4Output)
109+
}
110+
111+
return $invokePesterParams
112+
}
113+
114+
if ($All) {
115+
if ($pesterModule.Version -ge '5.0.0') {
116+
$configuration = @{
117+
Run = @{
118+
Path = $ScriptPath
119+
}
120+
}
121+
# only override this if user asks us to do it, to allow Pester to pick up
122+
# $PesterPreference from caller context and merge it with the configuration
123+
# we provide below, this way user can specify his output (and other) settings
124+
# using the standard [PesterConfiguration] object, and we can avoid providing
125+
# settings for everything
126+
if ("FromPreference" -ne $Output) {
127+
$configuration.Add('Output', @{ Verbosity = $Output })
128+
}
129+
130+
if ($OutputPath) {
131+
$configuration.Add('TestResult', @{
132+
Enabled = $true
133+
OutputPath = $OutputPath
134+
})
135+
}
136+
Pester\Invoke-Pester -Configuration $configuration | Out-Null
137+
}
138+
else {
139+
$invokePesterParams = Get-InvokePesterParams
140+
Pester\Invoke-Pester @invokePesterParams
141+
}
142+
}
143+
elseif (($LineNumber -match '\d+') -and ($pesterModule.Version -ge '4.6.0')) {
144+
if ($pesterModule.Version -ge '5.0.0') {
145+
$configuration = @{
146+
Run = @{
147+
Path = $ScriptPath
148+
}
149+
Filter = @{
150+
Line = "${ScriptPath}:$LineNumber"
151+
}
152+
}
153+
if ("FromPreference" -ne $Output) {
154+
$configuration.Add('Output', @{ Verbosity = $Output })
155+
}
156+
157+
if ($OutputPath) {
158+
$configuration.Add('TestResult', @{
159+
Enabled = $true
160+
OutputPath = $OutputPath
161+
})
162+
}
163+
164+
Pester\Invoke-Pester -Configuration $configuration | Out-Null
165+
}
166+
else {
167+
Pester\Invoke-Pester -Script $ScriptPath -PesterOption (New-PesterOption -ScriptBlockFilter @{
168+
IncludeVSCodeMarker=$true; Line=$LineNumber; Path=$ScriptPath}) -Show $pester4Output
169+
}
170+
}
171+
elseif ($TestName) {
172+
if ($pesterModule.Version -ge '5.0.0') {
173+
throw "Running tests by test name is unsafe. This should not trigger for Pester 5."
174+
}
175+
else {
176+
$invokePesterParams = Get-InvokePesterParams
177+
Pester\Invoke-Pester @invokePesterParams
178+
}
179+
}
180+
else {
181+
if ($pesterModule.Version -ge '5.0.0') {
182+
throw "Running tests by expandable string is unsafe. This should not trigger for Pester 5."
183+
}
184+
185+
# We get here when the TestName expression is of type ExpandableStringExpressionAst.
186+
# PSES will not attempt to "evaluate" the expression so it returns null for the TestName.
187+
Write-Warning "The Describe block's TestName cannot be evaluated. EXECUTING ALL TESTS instead."
188+
Write-Warning "To avoid this, install Pester >= 4.6.0 or remove any expressions in the TestName."
189+
190+
$invokePesterParams = Get-InvokePesterParams
191+
Pester\Invoke-Pester @invokePesterParams
192+
}

0 commit comments

Comments
 (0)