Public/Tests/New-PesterCustomTests.Tests.ps1
|
BeforeAll { $env:TCS_CONFIG_ROOT = Join-Path -Path $TestDrive -ChildPath 'config' $env:TCS_SKIP_UPDATE_CHECK = '1' $env:TCS_TELEMETRY_OPTOUT = '1' $ModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent Import-Module -Name (Join-Path -Path $ModuleRoot -ChildPath 'tcs.utils.psd1') -Force } AfterAll { Remove-Module -Name tcs.utils -Force -ErrorAction SilentlyContinue } Describe 'New-PesterCustomTests' { BeforeAll { function Get-ParseErrorCount { param([string]$Path) $tokens = $null $errors = $null $null = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$tokens, [ref]$errors) @($errors).Count } } BeforeEach { # A generated module with one public and one private function $Target = Join-Path -Path $TestDrive -ChildPath ([guid]::NewGuid().ToString('N')) $null = New-Item -Path $Target -ItemType Directory New-ModuleCustomTemplate -Names 'gen.tests' -Path $Target $Generated = Join-Path -Path $Target -ChildPath 'gen.tests' $PublicFolder = Join-Path -Path $Generated -ChildPath 'Public' $PrivateFolder = Join-Path -Path $Generated -ChildPath 'Private' New-FunctionTemplate -Name 'Get-Widget' -Path $PublicFolder New-FunctionTemplate -Name 'Get-Helper' -Path $PrivateFolder -ExcludeTelemetryCollection $Psd1 = Join-Path -Path $Generated -ChildPath 'gen.tests.psd1' (Get-Content -Path $Psd1 -Raw).Replace('FunctionsToExport = @()', "FunctionsToExport = @('Get-Widget')") | Set-Content -Path $Psd1 -NoNewline } It 'Creates a test per function in the default Tests folder' { New-PesterCustomTests -Source $PublicFolder $testFile = Join-Path -Path $PublicFolder -ChildPath 'Tests/Get-Widget.Tests.ps1' Test-Path -Path $testFile | Should -BeTrue Get-ParseErrorCount -Path $testFile | Should -Be 0 } It 'Uses the module-import header and no per-file PSScriptAnalyzer block' { New-PesterCustomTests -Source $PublicFolder $content = Get-Content -Path (Join-Path -Path $PublicFolder -ChildPath 'Tests/Get-Widget.Tests.ps1') -Raw $content | Should -Match ([regex]::Escape('Import-Module -Name (Join-Path -Path $ModuleRoot -ChildPath "$ModuleName.psd1") -Force')) $content | Should -Match ([regex]::Escape("`$env:TCS_TELEMETRY_OPTOUT = '1'")) $content | Should -Match "Describe 'Get-Widget'" $content | Should -Not -Match 'PSSA' $content | Should -Not -Match 'PSScriptAnalyzer' $content | Should -Not -Match 'Invoke-Expression' $content | Should -Not -Match '###TEMPLATE' } It 'Does not create a PSScriptAnalyzerSettings.psd1 file' { New-PesterCustomTests -Source $PublicFolder Get-ChildItem -Path $Generated -Recurse -Filter 'PSScriptAnalyzerSettings.psd1' | Should -BeNullOrEmpty } It 'Does not generate tests for existing test files' { New-PesterCustomTests -Source $PublicFolder New-PesterCustomTests -Source (Join-Path -Path $PublicFolder -ChildPath 'Tests') -WarningAction SilentlyContinue Get-ChildItem -Path $Generated -Recurse -Filter '*.Tests.Tests.ps1' | Should -BeNullOrEmpty } It 'Uses a private-function test for files in a Private folder' { New-PesterCustomTests -Source (Join-Path -Path $PrivateFolder -ChildPath 'Get-Helper.ps1') $content = Get-Content -Path (Join-Path -Path $PrivateFolder -ChildPath 'Tests/Get-Helper.Tests.ps1') -Raw $content | Should -Match 'InModuleScope' } It 'Writes to a custom destination and accepts piped files' { $destination = Join-Path -Path $Target -ChildPath 'custom-tests' Get-ChildItem -Path $PublicFolder -Filter '*.ps1' | New-PesterCustomTests -Destination $destination Test-Path -Path (Join-Path -Path $destination -ChildPath 'Get-Widget.Tests.ps1') | Should -BeTrue } It 'Keeps existing test files unless -Force is used' { $testFile = Join-Path -Path $PublicFolder -ChildPath 'Tests/Get-Widget.Tests.ps1' Set-Content -Path $testFile -Value '# my tests' New-PesterCustomTests -Source $PublicFolder -WarningVariable pesterWarnings -WarningAction SilentlyContinue (Get-Content -Path $testFile -Raw).Trim() | Should -Be '# my tests' $pesterWarnings | Should -Not -BeNullOrEmpty New-PesterCustomTests -Source $PublicFolder -Force Get-Content -Path $testFile -Raw | Should -Match "Describe 'Get-Widget'" } It 'Writes nothing to the pipeline' { New-PesterCustomTests -Source $PublicFolder | Should -BeNullOrEmpty } It 'Writes an error for a file that is not a .ps1' { $textFile = Join-Path -Path $Target -ChildPath 'notes.txt' Set-Content -Path $textFile -Value 'x' New-PesterCustomTests -Source $textFile -ErrorVariable pesterErrors -ErrorAction SilentlyContinue $pesterErrors | Should -Not -BeNullOrEmpty } It 'Creates nothing with -WhatIf' { New-PesterCustomTests -Source $PublicFolder -WhatIf Test-Path -Path (Join-Path -Path $PublicFolder -ChildPath 'Tests/Get-Widget.Tests.ps1') | Should -BeFalse } It 'Generates tests that pass against the generated module' { New-PesterCustomTests -Source $PublicFolder New-PesterCustomTests -Source $PrivateFolder # Run in a separate process with the same PowerShell engine and Pester version $engine = (Get-Process -Id $PID).Path $pesterVersion = (Get-Module -Name Pester).Version.ToString() $command = "`$ProgressPreference = 'SilentlyContinue'; Import-Module Pester -RequiredVersion $pesterVersion; " + "`$r = Invoke-Pester -Path '$Generated' -PassThru -Output None; '{0}/{1}' -f `$r.PassedCount, `$r.FailedCount" $result = & $engine -NoProfile -NonInteractive -Command $command $result | Select-Object -Last 1 | Should -Be '3/0' } } |