Function Test-FunctionNames { <# .SYNOPSIS Test that the name of the function/filter/workflow in the file match the name of the file and for verb match .DESCRIPTION Test that the name of the function/filter/workflow in the file match the name of the file and for verb match * This will look in public/private folders * This will examine for verb match to Get-Verb as part of the testing * This ignores any names that end with .tests.ps1 or .test.ps1 * This will check .tests?.ps1 files that they start with a reference to Load-PesterModules * If they don't, it will emit a warning per file The reason for these files to match their names is about process, not a functional concern. .EXAMPLE Test-FunctionNames .\Alkami.PowerShell.IIS\ .PARAMETER FolderPath The name of the folder to examine all files under #> [CmdletBinding()] Param ( [String]$FolderPath ) process { $verbs = Get-Verb | Select-Object -ExpandProperty Verb $badMatch = @() $files = (Get-ChildItem (Join-Path $FolderPath "*.ps1")) foreach($file in $files) { if ($file.FullName -match '(scratch|bak)') { Write-Verbose "Skipping $($file.FullName) for (scratch|bak)" continue } $content = (Get-Content $file) if ($file -match '\.Tests\.ps1' -or $file -match '\.Test\.ps1') { $firstLine = $content[0] if (([string]::IsNullOrWhitespace($firstLine) -or $firstLine -notmatch 'PesterModules') -and $firstline -notmatch "param") { Write-Warning "[$file] does not start with load-pestermodules or parameter declarations. You're gonna have a bad time." } elseif ($firstLine -match "param" -and ($null -eq ($content | Where-Object {$_ -match "PesterModules"}))) { Write-Warning "[$file] has a parameter declaration but does not include load-pestermodules. You're gonna have a bad time." } Write-Verbose "skipping testing of test $file" } else { $functionCandidate = $file.BaseName $keywordStartsLine = 0 $passing = $false foreach($line in $content) { ## Make sure the line doesn't start with whitespace and that people didn't put a bunch of spaces between 'keyword' and 'function-name' $line = ($line -replace '\s+',' ' -replace '^function','' -replace '^filter','' -replace '^workflow','').Trim() if ($line.StartsWith($functionCandidate, [StringComparison]::InvariantCultureIgnoreCase)) { $passing = $true ## we found the line we want break } $keywordStartsLine += 1 } # Make sure that the function name uses a good verb-naming pattern $verb = $functionCandidate.Split("-")[0] if($verbs -notcontains $verb) { $passing = $false Write-Warning "Function $functionCandidate (current verb: [$verb]) does not use a valid PowerShell verb. See: Get-Verb" } if ($keywordStartsLine -gt 1) { Write-Verbose "The file [$file] doesn't start with the keyword and function-name" } if (!$passing) { $badMatch += $functionCandidate } } } if ($badMatch.Length -gt 0) { $badMatch throw "The previous files failed their test constraints" } } }