Private/New-PstTestFile.ps1
|
# Helper functions must be defined before main function for cross-platform compatibility # These are called by New-PstTestFile and need to be in scope when the script is dot-sourced function Get-TestBeforeAllBlock { <# .SYNOPSIS Generates the BeforeAll block for Pester tests. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [ValidateSet('Function', 'Script', 'Module')] [string]$Type ) $sb = [System.Text.StringBuilder]::new() switch ($Type) { 'Function' { [void]$sb.AppendLine("BeforeAll {") [void]$sb.AppendLine(" # Import the function to test") [void]$sb.AppendLine(" . `$PSScriptRoot\..\src\Public\$Name.ps1") [void]$sb.AppendLine("}") } 'Script' { [void]$sb.AppendLine("BeforeAll {") [void]$sb.AppendLine(" # Define the script path") [void]$sb.AppendLine(" `$script:ScriptPath = `"`$PSScriptRoot\..\src\$Name.ps1`"") [void]$sb.AppendLine("}") } 'Module' { [void]$sb.AppendLine("BeforeAll {") [void]$sb.AppendLine(" # Import the module to test") [void]$sb.AppendLine(" `$ModulePath = `"`$PSScriptRoot\..\src\$Name`"") [void]$sb.AppendLine(" Import-Module `$ModulePath -Force") [void]$sb.AppendLine("}") [void]$sb.AppendLine() [void]$sb.AppendLine("AfterAll {") [void]$sb.AppendLine(" # Remove the module after testing") [void]$sb.AppendLine(" Remove-Module -Name $Name -Force -ErrorAction SilentlyContinue") [void]$sb.AppendLine("}") } } return $sb.ToString() } function Get-BasicTestContent { <# .SYNOPSIS Generates Basic complexity test content. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [ValidateSet('Function', 'Script', 'Module')] [string]$Type, [Parameter(Mandatory = $false)] [hashtable[]]$Parameters = @() ) $sb = [System.Text.StringBuilder]::new() [void]$sb.AppendLine("Describe `"$Name`" {") [void]$sb.AppendLine(" Context `"When valid parameters are provided`" {") # Happy path test if ($Type -eq 'Script') { [void]$sb.AppendLine(" It `"Should execute without errors`" {") [void]$sb.AppendLine(" # Arrange") [void]$sb.AppendLine(" # Set up any required test data") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Act & Assert") [void]$sb.AppendLine(" { & `$script:ScriptPath } | Should -Not -Throw") [void]$sb.AppendLine(" }") } else { [void]$sb.AppendLine(" It `"Should return expected output`" {") [void]$sb.AppendLine(" # Arrange") $paramExample = if ($Parameters.Count -gt 0) { $firstParam = $Parameters[0] "`$$($firstParam.Name) = `"TestValue`"" } else { "# Set up test data" } [void]$sb.AppendLine(" $paramExample") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Act") $callExample = if ($Parameters.Count -gt 0) { "`$result = $Name -$($Parameters[0].Name) `$$($Parameters[0].Name)" } else { "`$result = $Name" } [void]$sb.AppendLine(" $callExample") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Assert") [void]$sb.AppendLine(" `$result | Should -Not -BeNullOrEmpty") [void]$sb.AppendLine(" }") } [void]$sb.AppendLine(" }") # Parameter validation tests if ($Parameters.Count -gt 0) { [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"When invalid parameters are provided`" {") foreach ($param in $Parameters) { if ($param.Mandatory -eq $true) { [void]$sb.AppendLine(" It `"Should throw for null $($param.Name)`" {") [void]$sb.AppendLine(" { $Name -$($param.Name) `$null } | Should -Throw") [void]$sb.AppendLine(" }") } } [void]$sb.AppendLine(" }") } # Basic error handling test [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Error handling`" {") [void]$sb.AppendLine(" It `"Should handle errors gracefully`" {") [void]$sb.AppendLine(" # Test error handling behavior") [void]$sb.AppendLine(" # TODO: Add specific error scenario tests") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") [void]$sb.AppendLine("}") return $sb.ToString() } function Get-StandardTestContent { <# .SYNOPSIS Generates Standard complexity test content. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [ValidateSet('Function', 'Script', 'Module')] [string]$Type, [Parameter(Mandatory = $false)] [hashtable[]]$Parameters = @() ) $sb = [System.Text.StringBuilder]::new() [void]$sb.AppendLine("Describe `"$Name`" {") # Valid input context [void]$sb.AppendLine(" Context `"When valid input is provided`" {") if ($Type -eq 'Script') { [void]$sb.AppendLine(" It `"Should execute successfully`" {") [void]$sb.AppendLine(" { & `$script:ScriptPath } | Should -Not -Throw") [void]$sb.AppendLine(" }") } else { [void]$sb.AppendLine(" It `"Should return expected output type`" {") [void]$sb.AppendLine(" # Arrange") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" `$$($Parameters[0].Name) = `"TestValue`"") } [void]$sb.AppendLine() [void]$sb.AppendLine(" # Act") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" `$result = $Name -$($Parameters[0].Name) `$$($Parameters[0].Name)") } else { [void]$sb.AppendLine(" `$result = $Name") } [void]$sb.AppendLine() [void]$sb.AppendLine(" # Assert") [void]$sb.AppendLine(" `$result | Should -Not -BeNullOrEmpty") [void]$sb.AppendLine(" }") } [void]$sb.AppendLine(" }") # Invalid input context [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"When invalid input is provided`" {") if ($Parameters.Count -gt 0) { foreach ($param in $Parameters | Where-Object { $_.Mandatory -eq $true }) { [void]$sb.AppendLine(" It `"Should throw when $($param.Name) is null`" {") [void]$sb.AppendLine(" { $Name -$($param.Name) `$null } | Should -Throw") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should throw when $($param.Name) is empty`" {") [void]$sb.AppendLine(" { $Name -$($param.Name) '' } | Should -Throw") [void]$sb.AppendLine(" }") } } else { [void]$sb.AppendLine(" It `"Should validate input parameters`" {") [void]$sb.AppendLine(" # TODO: Add parameter validation tests") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") } [void]$sb.AppendLine(" }") # Edge cases context [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Edge cases`" {") [void]$sb.AppendLine(" It `"Should handle empty collections`" {") [void]$sb.AppendLine(" # TODO: Test with empty input collections") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should handle special characters`" {") [void]$sb.AppendLine(" # TODO: Test with special characters in input") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # Pipeline tests (for functions) if ($Type -eq 'Function') { [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Pipeline input`" {") [void]$sb.AppendLine(" It `"Should accept pipeline input`" {") [void]$sb.AppendLine(" # Arrange") [void]$sb.AppendLine(" `$inputData = @('Value1', 'Value2')") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Act & Assert") [void]$sb.AppendLine(" { `$inputData | $Name } | Should -Not -Throw") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") } # ShouldProcess tests if ($Type -eq 'Function') { [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"ShouldProcess support`" {") [void]$sb.AppendLine(" It `"Should support -WhatIf`" {") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" { $Name -$($Parameters[0].Name) `"Test`" -WhatIf } | Should -Not -Throw") } else { [void]$sb.AppendLine(" { $Name -WhatIf } | Should -Not -Throw") } [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should support -Confirm:`$false`" {") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" { $Name -$($Parameters[0].Name) `"Test`" -Confirm:`$false } | Should -Not -Throw") } else { [void]$sb.AppendLine(" { $Name -Confirm:`$false } | Should -Not -Throw") } [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") } # Error handling tests [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Error handling`" {") [void]$sb.AppendLine(" It `"Should throw terminating error for critical failures`" {") [void]$sb.AppendLine(" # TODO: Test terminating error scenarios") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should write non-terminating error for recoverable issues`" {") [void]$sb.AppendLine(" # TODO: Test non-terminating error scenarios") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # Output type tests [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Output validation`" {") [void]$sb.AppendLine(" It `"Should return correct output type`" {") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" `$result = $Name -$($Parameters[0].Name) `"Test`"") } else { [void]$sb.AppendLine(" `$result = $Name") } [void]$sb.AppendLine(" # TODO: Verify expected output type") [void]$sb.AppendLine(" `$result | Should -Not -BeNullOrEmpty") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") [void]$sb.AppendLine("}") return $sb.ToString() } function Get-AdvancedTestContent { <# .SYNOPSIS Generates Advanced complexity test content. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [ValidateSet('Function', 'Script', 'Module')] [string]$Type, [Parameter(Mandatory = $false)] [hashtable[]]$Parameters = @() ) $sb = [System.Text.StringBuilder]::new() [void]$sb.AppendLine("Describe `"$Name`" -Tag 'Unit' {") # BeforeEach for test isolation [void]$sb.AppendLine(" BeforeEach {") [void]$sb.AppendLine(" # Reset any module-level state before each test") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() # Valid input context [void]$sb.AppendLine(" Context `"When valid input is provided`" {") if ($Type -eq 'Script') { [void]$sb.AppendLine(" It `"Should execute successfully`" {") [void]$sb.AppendLine(" { & `$script:ScriptPath } | Should -Not -Throw") [void]$sb.AppendLine(" }") } else { [void]$sb.AppendLine(" It `"Should return expected output type`" {") [void]$sb.AppendLine(" # Arrange") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" `$$($Parameters[0].Name) = `"TestValue`"") } [void]$sb.AppendLine() [void]$sb.AppendLine(" # Act") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" `$result = $Name -$($Parameters[0].Name) `$$($Parameters[0].Name)") } else { [void]$sb.AppendLine(" `$result = $Name") } [void]$sb.AppendLine() [void]$sb.AppendLine(" # Assert") [void]$sb.AppendLine(" `$result | Should -Not -BeNullOrEmpty") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should return consistent results for same input`" {") [void]$sb.AppendLine(" # Arrange") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" `$$($Parameters[0].Name) = `"ConsistencyTest`"") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Act") [void]$sb.AppendLine(" `$result1 = $Name -$($Parameters[0].Name) `$$($Parameters[0].Name)") [void]$sb.AppendLine(" `$result2 = $Name -$($Parameters[0].Name) `$$($Parameters[0].Name)") } else { [void]$sb.AppendLine(" # Act") [void]$sb.AppendLine(" `$result1 = $Name") [void]$sb.AppendLine(" `$result2 = $Name") } [void]$sb.AppendLine() [void]$sb.AppendLine(" # Assert") [void]$sb.AppendLine(" `$result1 | Should -Be `$result2") [void]$sb.AppendLine(" }") } [void]$sb.AppendLine(" }") # Invalid input context [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"When invalid input is provided`" {") if ($Parameters.Count -gt 0) { foreach ($param in $Parameters | Where-Object { $_.Mandatory -eq $true }) { [void]$sb.AppendLine(" It `"Should throw when $($param.Name) is null`" {") [void]$sb.AppendLine(" { $Name -$($param.Name) `$null } | Should -Throw") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should throw when $($param.Name) is empty`" {") [void]$sb.AppendLine(" { $Name -$($param.Name) '' } | Should -Throw") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() } } [void]$sb.AppendLine(" It `"Should provide meaningful error messages`" {") [void]$sb.AppendLine(" # TODO: Verify error messages are descriptive") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # Edge cases context [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Edge cases`" {") [void]$sb.AppendLine(" It `"Should handle empty collections`" {") [void]$sb.AppendLine(" # TODO: Test with empty input collections") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should handle special characters`" {") [void]$sb.AppendLine(" # TODO: Test with special characters in input") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should handle maximum input sizes`" {") [void]$sb.AppendLine(" # TODO: Test with large input data") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should handle concurrent access`" {") [void]$sb.AppendLine(" # TODO: Test thread safety if applicable") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # Mock integration tests if ($Type -eq 'Function') { [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Mock integration`" {") [void]$sb.AppendLine(" BeforeAll {") [void]$sb.AppendLine(" # Set up mocks for external dependencies") [void]$sb.AppendLine(" Mock Write-Verbose { }") [void]$sb.AppendLine(" Mock Write-Debug { }") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should call expected dependencies`" {") [void]$sb.AppendLine(" # Arrange") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" `$$($Parameters[0].Name) = `"MockTest`"") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Act") [void]$sb.AppendLine(" $Name -$($Parameters[0].Name) `$$($Parameters[0].Name) -Verbose") } else { [void]$sb.AppendLine(" # Act") [void]$sb.AppendLine(" $Name -Verbose") } [void]$sb.AppendLine() [void]$sb.AppendLine(" # Assert") [void]$sb.AppendLine(" Should -Invoke Write-Verbose -Times 1 -Scope It") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should not call unexpected dependencies`" {") [void]$sb.AppendLine(" # TODO: Verify no unexpected external calls") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # Pipeline tests [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Pipeline input`" {") [void]$sb.AppendLine(" It `"Should accept pipeline input`" {") [void]$sb.AppendLine(" # Arrange") [void]$sb.AppendLine(" `$inputData = @('Value1', 'Value2', 'Value3')") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Act & Assert") [void]$sb.AppendLine(" { `$inputData | $Name } | Should -Not -Throw") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should process each pipeline item`" {") [void]$sb.AppendLine(" # Arrange") [void]$sb.AppendLine(" `$inputData = @('Item1', 'Item2', 'Item3')") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Act") [void]$sb.AppendLine(" `$results = `$inputData | $Name") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Assert") [void]$sb.AppendLine(" `$results.Count | Should -Be 3") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # ShouldProcess tests [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"ShouldProcess support`" {") [void]$sb.AppendLine(" It `"Should support -WhatIf`" {") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" { $Name -$($Parameters[0].Name) `"Test`" -WhatIf } | Should -Not -Throw") } else { [void]$sb.AppendLine(" { $Name -WhatIf } | Should -Not -Throw") } [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should not make changes with -WhatIf`" {") [void]$sb.AppendLine(" # TODO: Verify no changes are made when -WhatIf is used") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should support -Confirm:`$false`" {") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" { $Name -$($Parameters[0].Name) `"Test`" -Confirm:`$false } | Should -Not -Throw") } else { [void]$sb.AppendLine(" { $Name -Confirm:`$false } | Should -Not -Throw") } [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # Parameter set tests [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Parameter sets`" {") [void]$sb.AppendLine(" It `"Should use default parameter set`" {") [void]$sb.AppendLine(" `$command = Get-Command $Name") [void]$sb.AppendLine(" `$command.DefaultParameterSet | Should -Not -BeNullOrEmpty") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should have mutually exclusive parameter sets`" {") [void]$sb.AppendLine(" # TODO: Verify parameter set constraints") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") } # Error handling tests [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Error handling`" {") [void]$sb.AppendLine(" It `"Should throw terminating error for critical failures`" {") [void]$sb.AppendLine(" # TODO: Test terminating error scenarios") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should write non-terminating error for recoverable issues`" {") [void]$sb.AppendLine(" # TODO: Test non-terminating error scenarios") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should include error details in ErrorRecord`" {") [void]$sb.AppendLine(" # TODO: Verify ErrorRecord contains proper details") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # Performance tests [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Performance`" -Tag 'Performance' {") [void]$sb.AppendLine(" It `"Should complete within acceptable time`" {") [void]$sb.AppendLine(" # Arrange") [void]$sb.AppendLine(" `$maxTime = 5000 # milliseconds") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Act") [void]$sb.AppendLine(" `$elapsed = Measure-Command {") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" $Name -$($Parameters[0].Name) `"PerfTest`"") } else { [void]$sb.AppendLine(" $Name") } [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" # Assert") [void]$sb.AppendLine(" `$elapsed.TotalMilliseconds | Should -BeLessThan `$maxTime") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should handle large datasets efficiently`" {") [void]$sb.AppendLine(" # TODO: Test with large input datasets") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # Security tests [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Security`" -Tag 'Security' {") [void]$sb.AppendLine(" It `"Should not expose sensitive data in errors`" {") [void]$sb.AppendLine(" # TODO: Verify error messages don't leak sensitive info") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should validate and sanitize input`" {") [void]$sb.AppendLine(" # TODO: Test input sanitization") [void]$sb.AppendLine(" `$true | Should -BeTrue") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # Output type tests [void]$sb.AppendLine() [void]$sb.AppendLine(" Context `"Output validation`" {") [void]$sb.AppendLine(" It `"Should return correct output type`" {") if ($Parameters.Count -gt 0) { [void]$sb.AppendLine(" `$result = $Name -$($Parameters[0].Name) `"TypeTest`"") } else { [void]$sb.AppendLine(" `$result = $Name") } [void]$sb.AppendLine(" # TODO: Verify expected output type") [void]$sb.AppendLine(" `$result | Should -Not -BeNullOrEmpty") [void]$sb.AppendLine(" }") [void]$sb.AppendLine() [void]$sb.AppendLine(" It `"Should match OutputType attribute`" {") [void]$sb.AppendLine(" `$command = Get-Command $Name") [void]$sb.AppendLine(" `$outputTypes = `$command.OutputType") [void]$sb.AppendLine(" `$outputTypes | Should -Not -BeNullOrEmpty") [void]$sb.AppendLine(" }") [void]$sb.AppendLine(" }") # Code coverage note [void]$sb.AppendLine() [void]$sb.AppendLine(" # Target: 90%+ code coverage") [void]$sb.AppendLine(" # Run with: Invoke-Pester -CodeCoverage @{ Path = '.\src\$Name.ps1' }") [void]$sb.AppendLine("}") return $sb.ToString() } # Main function - defined after helper functions for cross-platform compatibility function New-PstTestFile { <# .SYNOPSIS Generates Pester 5.x test file content based on complexity level. .DESCRIPTION Creates Pester test file content for PowerShell functions, scripts, or modules. The generated tests follow best practices and vary in comprehensiveness based on the specified complexity level: - Basic: Single Describe block with happy path and parameter validation tests - Standard: Multiple Context blocks with pipeline, ShouldProcess, and error tests - Advanced: Comprehensive tests with mocks, parameter sets, and performance tests .PARAMETER Name The name of the function, script, or module to generate tests for. .PARAMETER Type The type of artifact: Function, Script, or Module. .PARAMETER Complexity The complexity level: Basic, Standard, or Advanced. .PARAMETER Parameters Array of parameter hashtables for the function/script being tested. .PARAMETER OutputPath Optional path where the test file should be created. If not specified, returns the content as a string. .EXAMPLE New-PstTestFile -Name "Get-UserData" -Type Function -Complexity Basic Generates basic Pester tests for the Get-UserData function. .EXAMPLE New-PstTestFile -Name "DataProcessor" -Type Script -Complexity Standard -OutputPath ".\tests\Unit\" Creates a Standard complexity test file for the DataProcessor script. .NOTES Version: 1.0 Author: numidia Creation Date: 2025-12-05 Purpose: Auto-generate Pester tests based on complexity level #> [CmdletBinding(SupportsShouldProcess)] [OutputType([string])] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [ValidateSet('Function', 'Script', 'Module')] [string]$Type, [Parameter(Mandatory = $true)] [ValidateSet('Basic', 'Standard', 'Advanced')] [string]$Complexity, [Parameter(Mandatory = $false)] [hashtable[]]$Parameters = @(), [Parameter(Mandatory = $false)] [string]$OutputPath ) begin { Write-Debug "Begin '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'" } process { try { $sb = [System.Text.StringBuilder]::new() # Generate BeforeAll block based on type $beforeAllContent = Get-TestBeforeAllBlock -Name $Name -Type $Type # Generate test content based on complexity $testContent = switch ($Complexity) { 'Basic' { Get-BasicTestContent -Name $Name -Type $Type -Parameters $Parameters } 'Standard' { Get-StandardTestContent -Name $Name -Type $Type -Parameters $Parameters } 'Advanced' { Get-AdvancedTestContent -Name $Name -Type $Type -Parameters $Parameters } } [void]$sb.Append($beforeAllContent) [void]$sb.AppendLine() [void]$sb.Append($testContent) $result = $sb.ToString() # Output to file if path specified if ($OutputPath) { $fileName = "$Name.Tests.ps1" $fullPath = Join-Path $OutputPath $fileName # Ensure directory exists $directory = Split-Path $fullPath -Parent if (-not (Test-Path $directory)) { if ($PSCmdlet.ShouldProcess($directory, "Create directory")) { New-Item -Path $directory -ItemType Directory -Force | Out-Null } } if ($PSCmdlet.ShouldProcess($fullPath, "Create test file")) { $result | Set-Content -Path $fullPath -Encoding UTF8 Write-Verbose "Created test file: $fullPath" } return $fullPath } return $result } catch { $PSCmdlet.ThrowTerminatingError($_) } } end { Write-Debug "End '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'" } } |