-
Notifications
You must be signed in to change notification settings - Fork 29
/
New-PesterTests.ps1
138 lines (129 loc) · 4.51 KB
/
New-PesterTests.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<#
.SYNOPSIS
Creates a new Pester testing script from a script's examples and parameter sets.
.FUNCTIONALITY
Scripts
.LINK
Stop-ThrowError.ps1
.EXAMPLE
New-PesterTests.ps1 New-PesterTests.ps1
Creates .\test\New-PesterTests.Tests.ps1 with some boilerplate Pester code.
#>
#Requires -Version 3
[CmdletBinding()] Param(
# The script to generate tests for.
[Parameter(ParameterSetName='Script',Position=0,Mandatory=$true,ValueFromPipeline=$true)]
[ValidateScript({Test-Path $_ -Type Leaf})][string] $Script,
# The directory to generate tests in.
[ValidateScript({Test-Path $_ -Type Container})][string] $Directory = 'test',
# Overwrite an existing tests file.
[Parameter(ParameterSetName='Script')][switch] $Force,
# Indicates that the next script that's missing a test script file should have one created.
[Parameter(ParameterSetName='Next',Mandatory=$true)][switch] $Next
)
Begin
{
if($PSCmdlet.ParameterSetName -eq 'Next')
{
if(!$Next) {return}
else
{
$nextScript = Get-Item *.ps1 |
Where-Object {!(Join-Path $Directory ([io.path]::ChangeExtension($_.Name,'Tests.ps1')) |Test-Path -Type Leaf)} |
Select-Object -First 1
if(!$nextScript)
{
Write-Info.ps1 'Congratulations, all of the scripts in this directory have test files.' -ForegroundColor Green
return
}
else
{
Write-Info.ps1 "Creating new tests script for $nextScript" -ForegroundColor Green
return &$PSCommandPath -Script $nextScript -Directory $Directory
}
}
}
Import-CharConstants.ps1 NL -Scope Script
filter Format-ExampleTest
{
Param(
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][string] $Title,
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][psobject[]] $Introduction,
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][string] $Code,
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][psobject[]] $Remarks
)
$cmdtext = (($Introduction |Where-Object Text -notin 'PS > ',' ','',$null |Select-Object -ExpandProperty Text) -join $NL) + $Code
$output = ($Remarks |Where-Object {$_.Text} |Select-Object -ExpandProperty Text) -join $NL
return @"
It "$($Title.Trim(' -'))" -Skip {
$cmdtext |Should -BeExactly @"
$output
$('"@')
}
"@
}
filter Format-ParameterSetContext
{
Param(
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][ValidateNotNullOrEmpty()][string] $Name
)
if([string]::IsNullOrWhiteSpace($Name)) {return}
return @"
Context '$Name' -Tag $Name {
It "test" -Skip {
1 |Should -Be 1
}
}
"@
}
filter Format-ScriptPesterTest
{
Param(
[Parameter(Position=0,Mandatory=$true)][string] $Name,
[Parameter(Position=0,Mandatory=$true)][Management.Automation.CommandInfo] $CmdInfo,
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][string] $Synopsis,
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][psobject[]] $Examples
)
$shortname = Split-Path $Name -LeafBase
$Local:OFS = $NL
return @"
<#
.SYNOPSIS
Tests $Synopsis
#>
`$basename = "`$((`$MyInvocation.MyCommand.Name -split '\.',2)[0])."
`$skip = !(Test-Path .changes -Type Leaf) ? `$false :
!@(Get-Content .changes |Get-Item |Select-Object -ExpandProperty Name |Where-Object {`$_.StartsWith(`$basename)})
if(`$skip) {Write-Information "No changes to `$basename" -infa Continue}
Describe '$shortname' -Tag $shortname -Skip:`$skip {
BeforeAll {
`$scriptsdir,`$sep = (Split-Path `$PSScriptRoot),[io.path]::PathSeparator
if(`$scriptsdir -notin (`$env:Path -split `$sep)) {`$env:Path += "`$sep`$scriptsdir"}
}
Context '$($Synopsis -replace "'","''")' -Tag Example {
$($Examples.example |Format-ExampleTest)
}
$($CmdInfo.ParameterSets |Where-Object Name -ne __AllParameterSets |Format-ParameterSetContext)
}
"@
}
}
Process
{
if($PSCmdlet.ParameterSetName -eq 'Next') {return}
$name = Split-Path $Script -Leaf
$cmd = Resolve-Path $Script |Get-Command
$testfile = Join-Path $Directory ([io.path]::ChangeExtension($name,'Tests.ps1'))
if((Test-Path $testfile -Type Leaf) -and !$Force)
{
Stop-ThrowError.ps1 "File '$testfile' already exists" -Argument Script
}
Get-Help (Resolve-Path $Script) |
Format-ScriptPesterTest -Name $name -CmdInfo $cmd |
Out-File $testfile -Encoding utf8BOM
if((Get-Variable psEditor -Scope Global -ErrorAction Ignore) -and (Test-Path $testfile -Type Leaf))
{
$psEditor.Workspace.OpenFile($Script, $false)
$psEditor.Workspace.OpenFile($testfile, $false)
}
}