diff --git a/src/functions/Coverage.ps1 b/src/functions/Coverage.ps1 index a65784ee3..03fb25aa6 100644 --- a/src/functions/Coverage.ps1 +++ b/src/functions/Coverage.ps1 @@ -727,11 +727,23 @@ function Get-CoverageReport { } function Get-ReportRoot { - if ($null -ne $PesterPreference.CodeCoverage.ReportRoot.Value) { - return $PesterPreference.CodeCoverage.ReportRoot.Value + $reportRoot = if ($null -ne $PesterPreference.CodeCoverage.ReportRoot.Value) { + $PesterPreference.CodeCoverage.ReportRoot.Value + } + else { + $PesterPreference.Run.RepoRoot.Value + } + + if ([string]::IsNullOrEmpty($reportRoot)) { + return $reportRoot } - $PesterPreference.Run.RepoRoot.Value + # Resolve to an absolute path. Get-RelativePath strips this prefix off the + # (absolute) file paths, so a relative ReportRoot/RepoRoot would never match + # and the report would keep the absolute paths instead of making them + # relative (#2920). GetUnresolvedProviderPathFromPSPath resolves against the + # current location without requiring the path to exist. + $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($reportRoot) } function Get-RelativePath { diff --git a/tst/functions/Coverage.Tests.ps1 b/tst/functions/Coverage.Tests.ps1 index 29f23db4f..dda93ff78 100644 --- a/tst/functions/Coverage.Tests.ps1 +++ b/tst/functions/Coverage.Tests.ps1 @@ -1414,4 +1414,30 @@ InPesterModuleScope { # } # } # } + + Describe 'Get-ReportRoot' { + It 'resolves a relative CodeCoverage.ReportRoot to an absolute path (#2920)' { + $PesterPreference = [PesterConfiguration]::Default + $PesterPreference.CodeCoverage.ReportRoot = '.' + [System.IO.Path]::IsPathRooted((Get-ReportRoot)) | Should -BeTrue + } + + It 'resolves a relative Run.RepoRoot fallback to an absolute path (#2920)' { + $PesterPreference = [PesterConfiguration]::Default + $PesterPreference.Run.RepoRoot = '.' + [System.IO.Path]::IsPathRooted((Get-ReportRoot)) | Should -BeTrue + } + + It 'lets a relative ReportRoot still yield relative file paths in the report (#2920)' { + # Reproduces #2920: with a relative ReportRoot, Get-RelativePath could + # not strip the prefix from the absolute file paths, so the report kept + # the absolute paths. Get-ReportRoot now resolves to absolute first. + $PesterPreference = [PesterConfiguration]::Default + $PesterPreference.CodeCoverage.ReportRoot = '.' + $absRoot = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath('.') + $absFile = Join-Path -Path $absRoot -ChildPath (Join-Path 'sub' 'File.ps1') + $expected = 'sub{0}File.ps1' -f [System.IO.Path]::DirectorySeparatorChar + Get-RelativePath -Path $absFile -RelativeTo (Get-ReportRoot) | Should -Be $expected + } + } }