Skip to content

Commit

Permalink
Fix wildcards in dirs (pester#1858)
Browse files Browse the repository at this point in the history
* Fix resolving paths from wildcards in directories
  • Loading branch information
nohwnd authored Mar 5, 2021
1 parent da5f776 commit 8ccfdc5
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 24 deletions.
71 changes: 47 additions & 24 deletions src/Pester.RSpec.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,55 @@ function Find-File {
}

if ((& $script:SafeCommands['Test-Path'] $p)) {
$item = & $SafeCommands['Get-Item'] $p

if ($item.PSIsContainer) {
# this is an existing directory search it for tests file
& $SafeCommands['Get-ChildItem'] -Recurse -Path $p -Filter "*$Extension" -File
continue
}

if ("FileSystem" -ne $item.PSProvider.Name) {
# item is not a directory and exists but is not a file so we are not interested
continue
}

if (".ps1" -ne $item.Extension) {
& $SafeCommands['Write-Error'] "Script path '$p' is not a ps1 file." -ErrorAction Stop
# This can expand to more than one path when wildcard is used, those paths can be folders or files.
# We want to avoid expanding to paths that are not matching our filters, but also want to ensure that if
# user passes in MyTestFile.ps1 without the .Tests.ps1 it will still run.

# So at this step we look if we expanded the path to more than 1 item and use stricter rules with filtering.
# Or if the file was just a single file, we won't use stricter filtering for files.

# This allows us to use wildcards to get all .Tests.ps1 in the folder and all child folders, which is very useful.
# But prevents a rare scenario where you provide C:\files\*\MyTest.ps1, because in that case only .Tests.ps1 would be included.

$items = & $SafeCommands['Get-Item'] $p
$resolvedToMultipleFiles = $null -ne $items -and 1 -lt @($items).Length

foreach ($item in $items) {
if ($item.PSIsContainer) {
# this is an existing directory search it for tests file
& $SafeCommands['Get-ChildItem'] -Recurse -Path $item -Filter "*$Extension" -File
}
elseif ("FileSystem" -ne $item.PSProvider.Name) {
# item is not a directory and exists but is not a file so we are not interested
}
elseif ($resolvedToMultipleFiles) {
# item was resolved from a wildcarded path only use it if it has test extension
if ($item.FullName -like "*$Extension")
{
# add unresolved path to have a note of the original path used to resolve this
& $SafeCommands['Add-Member'] -Name UnresolvedPath -Type NoteProperty -Value $p -InputObject $item
$item
}
}
else {
# this is some file, that was either provided directly, or resolved from wildcarded path as a single item,
# we don't care what type of file it is, or if it has test extension (.Tests.ps1) we should try to run it
# to allow any file that is provided directly to run
if (".ps1" -ne $item.Extension) {
& $SafeCommands['Write-Error'] "Script path '$item' is not a ps1 file." -ErrorAction Stop
}

# add unresolved path to have a note of the original path used to resolve this
& $SafeCommands['Add-Member'] -Name UnresolvedPath -Type NoteProperty -Value $p -InputObject $item
$item
}
}

# this is some file, we don't care if it is just a .ps1 file or .Tests.ps1 file
& $SafeCommands['Add-Member'] -Name UnresolvedPath -Type NoteProperty -Value $p -InputObject $item
$item
continue
}

# this is a path that does not exist so let's hope it is
# a wildcarded path that will resolve to some files
& $SafeCommands['Get-ChildItem'] -Recurse -Path $p -Filter "*$Extension" -File
else {
# this is a path that does not exist so let's hope it is
# a wildcarded path that will resolve to some files
& $SafeCommands['Get-ChildItem'] -Recurse -Path $p -Filter "*$Extension" -File
}
}

Filter-Excluded -Files $files -ExcludePath $ExcludePath | & $SafeCommands['Where-Object'] { $_ }
Expand Down
53 changes: 53 additions & 0 deletions tst/Pester.RSpec.ts.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,59 @@ i -PassThru:$PassThru {
}
}

t "Providing path with wildcard that is in directory names should expand to all directories and all their test files" {
try {
$sb = {
param (
[int] $Value
)

if ($Value -ne 1 -and $Value -ne 2) {
throw "Expected `$Value to be 1 or 2 but it is, '$Value'"
}

Describe "d1" {
It "t1" {
if ($Value -ne 1 -and $Value -ne 2) {
throw "Expected `$Value to be 1 or 2 but it is, '$Value'"
}
}
}
}

$tmp = "$([IO.Path]::GetTempPath())/$([Guid]::NewGuid())"
$tmp1 = $tmp + "PrefixDir1"
$tmp2 = $tmp + "PrefixDir2"
$null = New-Item ($tmp1) -Force -ItemType Container
$null = New-Item ($tmp2) -Force -ItemType container
$file1 = "$tmp1/file1.Tests.ps1"
$file2 = "$tmp2/file2.Tests.ps1"
$sb | Set-Content -Path $file1
$sb | Set-Content -Path $file2

# passing path to a wildcarded directory, that only uses part of the name as prefix
$container = New-PesterContainer -Path ($tmp + "Prefix*" ) -Data @(
@{ Value = 1 }
@{ Value = 2 }
)

$r = Invoke-Pester -Container $container -PassThru # -Output Normal
$r.Containers[0].Blocks[0].Tests[0].Result | Verify-Equal "Passed"
$r.Containers[1].Blocks[0].Tests[0].Result | Verify-Equal "Passed"
$r.Containers[2].Blocks[0].Tests[0].Result | Verify-Equal "Passed"
$r.Containers[3].Blocks[0].Tests[0].Result | Verify-Equal "Passed"
}
finally {
if ($null -ne $file1 -and (Test-Path $file1)) {
Remove-Item $file1 -Force
}

if ($null -ne $file2 -and (Test-Path $file2)) {
Remove-Item $file2 -Force
}
}
}

t "Providing -Path that resolves to the same path as a parametrized script should skip that path" {
try {
$sb1 = {
Expand Down

0 comments on commit 8ccfdc5

Please sign in to comment.