tests/Unit.Tests.ps1
$ModuleBase = Split-Path -Parent $MyInvocation.MyCommand.Path # For tests in .\Tests subdirectory if ((Split-Path $ModuleBase -Leaf) -eq 'Tests') { $ModuleBase = Split-Path $ModuleBase -Parent } $tokens = $null $errors = $null Describe "Checking that each dbachecks Pester test is correctly formatted for Power Bi and Coded correctly" { $Checks = (Get-ChildItem $ModuleBase\checks).Where{$_.Name -ne 'MaintenanceSolution.Tests.ps1'} $Checks.Foreach{ $Check = Get-Content $Psitem.FullName -Raw Context "$($_.Name) - Checking Describes titles and tags" { $UniqueTags = (Get-DbcCheck).UniqueTag ## This gets all of the code with a describe $Describes = [Management.Automation.Language.Parser]::ParseInput($check, [ref]$tokens, [ref]$errors). FindAll([Func[Management.Automation.Language.Ast, bool]] { param ($ast) $ast.CommandElements -and $ast.CommandElements[0].Value -eq 'describe' }, $true) | ForEach { $CE = $_.CommandElements $secondString = ($CE | Where { $_.StaticType.name -eq 'string' })[1] $tagIdx = $CE.IndexOf(($CE | Where ParameterName -eq 'Tags')) + 1 $tags = if ($tagIdx -and $tagIdx -lt $CE.Count) { $CE[$tagIdx].Extent } New-Object PSCustomObject -Property @{ Name = $secondString Tags = $tags } } @($describes).Foreach{ $title = $PSItem.Name.ToString().Trim('"').Trim('''') It "$title Should Use a double quote after the Describe" { $PSItem.Name.ToString().Startswith('"') | Should -BeTrue -Because 'We need use double quotes for titles' $PSItem.Name.ToString().Endswith('"') | Should -BeTrue -Because 'We need use double quotes for titles' } It "$title should use a plural for tags" { $PsItem.Tags | Should -Not -BeNullOrEmpty -Because 'We use the plural of Tags' } # a simple test for no esses apart from statistics and Access!! if ($null -ne $PSItem.Tags) { $PSItem.Tags.Text.Split(',').Trim().Where{($_ -ne '$filename') -and ($_ -notlike '*statistics*') -and ($_ -notlike '*BackupPathAccess*') }.ForEach{ It "$PsItem Should Be Singular" { $_.ToString().Endswith('s') | Should -BeFalse -Because 'Our coding standards say tags should be singular' } } It "The first Tag $($PSItem.Tags.Text.Split(',')[0]) Should Be in the unique Tags returned from Get-DbcCheck" { $UniqueTags | Should -Contain $PSItem.Tags.Text.Split(',')[0].ToString() -Because 'We need a unique tag for each test' } } else { It "You haven't used the Tags Parameter so we can't check the tags" { $false | Should -BeTrue -Because 'We use teh Tags parameter' } } } } Context "$($_.Name) - Checking Contexts" { ## Find the Contexts $Contexts = [Management.Automation.Language.Parser]::ParseInput($check, [ref]$tokens, [ref]$errors). FindAll([Func[Management.Automation.Language.Ast, bool]] { param ($ast) $ast.CommandElements -and $ast.CommandElements[0].Value -eq 'Context' }, $true) | ForEach { $CE = $_.CommandElements $secondString = ($CE | Where { $_.StaticType.name -eq 'string' })[1] New-Object PSCustomObject -Property @{ Name = $secondString } } @($Contexts).ForEach{ $title = $PSItem.Name.ToString().Trim('"').Trim('''') It "$Title Should end with `$psitem (or `$cluster) So that the PowerBi will work correctly" { $PSItem.Name.ToString().Endswith('psitem"') -or $PSItem.Name.ToString().Endswith('cluster"') | Should -BeTrue -Because 'This helps the PowerBi to parse the data' } } } Context "$($_.Name) - Checking Code" { ## This just grabs all the code $AST = [System.Management.Automation.Language.Parser]::ParseInput($Check, [ref]$null, [ref]$null) $Statements = $AST.EndBlock.statements.Extent ## Ignore the filename line @($Statements.Where{$_.StartLineNumber -ne 1}).ForEach{ $title = [regex]::matches($PSItem.text, "Describe(.*)-Tag").groups[1].value.Replace('"', '').Replace('''', '').trim() It "$title Should Use Get-SqlInstance or Get-ComputerName" { ($PSItem.text -Match 'Get-SqlInstance') -or ($psitem.text -match 'Get-ComputerName') | Should -BeTrue -Because 'These are the commands to use to get Instances or Computers' } if ($title -ne 'Cluster Health') { It "$title Should use the ForEach Method" { ($Psitem.text -match 'Get-SqlInstance\).ForEach{' ) -or ($Psitem.text -match 'Get-ComputerName\).ForEach{' ) | Should -BeTrue # use the \ to escape the ) -Because 'We use the ForEach method in our coding standards' } } It "$title Should not use `$_" { ($Psitem.text -match '$_' )| Should -BeFalse -Because '¬$psitem is the correct one to use' } It "$title Should Contain a Context Block" { $Psitem.text -match 'Context' | Should -BeTrue -Because 'This helps the Power Bi' } } } } } |