sigmadb.Tests.ps1
# Set-StrictMode -Version latest BeforeDiscovery { #region Get functionsPaths if (Test-Path "$PSScriptRoot\Public\*.ps1") { $functionPaths += Get-ChildItem -Path "$PSScriptRoot\Public\*.ps1" -Exclude "*.Tests.*" } <# TODO: Implement testing in private functions (at least 80-90% should already be covered by the public functions) $functionPaths = @() if (Test-Path "$PSScriptRoot\Private\*.ps1") { $functionPaths += Get-ChildItem -Path "$PSScriptRoot\Private\*.ps1" -Exclude "*.Tests.*" } #> #endregion #region Get functions data $functions = @() foreach ($function in $functionPaths) { $abstractSyntaxTree = [System.Management.Automation.Language.Parser]::ParseInput((Get-Content -Raw $function.FullName), [ref]$null, [ref]$null) $astSearchDelegate = { $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] } $parsedFunction = $abstractSyntaxTree.FindAll($astSearchDelegate, $true) | Where-Object Name -eq $function.BaseName $functions += @{ Name = $function.BaseName Path = $function.FullName HelpContent = $parsedFunction.GetHelpContent() Parameters = $parsedFunction.Body.ParamBlock.Parameters.Name.VariablePath.UserPath } } } BeforeAll { # Current location $script:here = $PSScriptRoot #region Reloading SUT # Ensuring that we are testing this version of module and not any other version that could be in memory $modulePath = "$($PSCommandPath -replace '.Tests.ps1$', '').psm1" $moduleName = (($modulePath | Split-Path -Leaf) -replace '.psm1') @(Get-Module -Name $moduleName).where({ $_.version -ne '0.0' }) | Remove-Module # Removing all module versions from the current context if there are any Import-Module -Name $modulePath -Force -ErrorAction Stop # Loading module explicitly by path and not via the manifest #endregion } # Running tests for the module Describe "<moduleName>" { Context 'Module Setup' { It "should have a root module" { Test-Path $modulePath | Should -Be $true } It "should have an associated manifest" { Test-Path "$here\$moduleName.psd1" | Should -Be $true } It "should have public functions" { Test-Path "$here\Public\*.ps1" | Should -Be $true } It "should be a valid PowerShell code" { $psFile = Get-Content -Path $modulePath -ErrorAction Stop $errors = $null $null = [System.Management.Automation.PSParser]::Tokenize($psFile, [ref]$errors) $errors.Count | Should -Be 0 } } Context "Module Control" { It "should import without errors" { { Import-Module -Name $modulePath -Force -ErrorAction Stop } | Should -Not -Throw Get-Module -Name $moduleName | Should -Not -BeNullOrEmpty } It 'should remove without errors' { { Remove-Module -Name $moduleName -ErrorAction Stop } | Should -Not -Throw Get-Module -Name $moduleName | Should -BeNullOrEmpty } } } Describe "<Name>" -ForEach $functions { Context 'Function Code Style Tests' { It "should be an advanced function" { $Path | Should -FileContentMatch 'Function' $Path | Should -FileContentMatch 'CmdletBinding' $Path | Should -FileContentMatch 'Param' } <# TODO: Implement verbosity in every function It "should contain Write-Verbose blocks" { $Path | Should -FileContentMatch 'Write-Verbose' } #> It "should be a valid PowerShell code" { $psFile = Get-Content -Path $Path -ErrorAction Stop $errors = $null $null = [System.Management.Automation.PSParser]::Tokenize($psFile, [ref]$errors) $errors.Count | Should -Be 0 } It "should have tests" { $testFile = ($Path -replace ".ps1", ".Tests.ps1") Test-Path $testFile | Should -Be $true $testFile | Should -FileContentMatch ('Describe .*' + $Name + '.*') } } Context "Function Help Quality Tests" { It "should have a SYNOPSIS" { $HelpContent.Synopsis | Should -Not -BeNullOrEmpty } It "should have a DESCRIPTION with length > 40 symbols" { $HelpContent.Description.Length | Should -BeGreaterThan 40 } It "should have at least one EXAMPLE" { $HelpContent.Examples.Count | Should -BeGreaterThan 0 $HelpContent.Examples[0] | Should -Match ([regex]::Escape($Name)) $HelpContent.Examples[0] | Should -BeGreaterThan ($Name.Length + 10) } It "should have descriptive help for '<_>' parameter" -TestCases $Parameters { $HelpContent.Parameters.($_.ToUpper()) | Should -Not -BeNullOrEmpty $HelpContent.Parameters.($_.ToUpper()).Length | Should -BeGreaterThan 25 } } } |