Private/Tests/AKPT.Tests.ps1

<#
 
# UTest AKPT Module
 
Pester UTest für diese Module AKPT.
 
- **Hashtags** UTest Pester Module
- **Version** 2020.20.09
#>


BeforeAll {
    Split-Path -Path $PSCommandPath -Parent | Split-Path -Parent | Split-Path -Parent | Set-Location
    $PSCommandPath | Write-Warning
}

Describe "Module AKPT" -Tag 'Compliance' {

    It 'Alle Test sind fehlerfrei' {
        $config = [PesterConfiguration]::Default

        $config.Debug.ShowNavigationMarkers = $true

        $config.CodeCoverage.Enabled = $false
        $config.CodeCoverage.OutputEncoding = 'UTF8'
        $config.CodeCoverage.OutputFormat = 'JaCoCo'
        $config.CodeCoverage.Path = "$($PSCommandPath.Replace('\AKPT\Private\Tests\AKPT.Tests.ps1', ''))\AKPT\Public\*.ps1"
        $config.CodeCoverage.OutputPath = "$($PSCommandPath.Replace('\AKPT\Private\Tests\AKPT.Tests.ps1', ''))\AKPT\Private\Tests\AKPT.CodeCoverage.xml"

        $config.TestResult.Enabled = $true
        $config.TestResult.OutputPath = "$($PSCommandPath.Replace('\AKPT\Private\Tests\AKPT.Tests.ps1', ''))\AKPT\Private\Tests\AKPT.TestResults.xml"
        $config.TestResult.OutputEncoding = 'UTF8'
        $config.TestResult.OutputFormat = 'NUnitXml'

        $config.Run.PassThru = $true
        $config.Run.Path =  "$($PSCommandPath.Replace('\AKPT\Private\Tests\AKPT.Tests.ps1', ''))\AKPT\Private\Tests\"
        $config.Run.ExcludePath = $PSCommandPath

        Invoke-Pester -Configuration $config | Select-Object -ExpandProperty 'FailedCount' | Should -Be 0
    }

    Context 'Basic Module Testing' {

        $testCases = Get-ChildItem '.\..\..\Public\*.ps1' -File -Force | ForEach-Object -Process { return @{ Path=$_.FullName } }

        It "Script <Path> should be valid powershell" -TestCases $testCases  {
            $contents = Get-Content -Path $Path -ErrorAction Stop
            $errors = $null
            $null = [System.Management.Automation.PSParser]::Tokenize($contents, [ref]$errors)
            $errors.Count | Should -Be 0
        }

        It "Modul AKPT problemlos importiert" {
            Remove-Module -Name 'AKPT' -Force -ErrorAction Ignore -WarningAction Ignore
            { Import-Module -Name '.\AKPT.psd1' -Force } | Should -Not -Throw
        }

        It "Module AKPT problemlos entladen" {
            Import-Module -Name '.\AKPT.psd1' -Force
            { Remove-Module -Name 'AKPT' -Force } | Should -Not -Throw
        }
    }

    Context 'Manifest Testing' {

        It 'Valid Module Manifest' {
            { Test-ModuleManifest -Path .\AKPT.psd1 -ErrorAction Stop -WarningAction SilentlyContinue } | Should -Not -Throw
        }
        It 'Valid Manifest Name' {
            Test-ModuleManifest -Path .\AKPT.psd1 | Select-Object -ExpandProperty Name | Should -Be 'AKPT'
        }
        It 'Generic Version Check' {
            (Test-ModuleManifest -Path .\AKPT.psd1 | Select-Object -ExpandProperty Version) -as [Version] | Should -Not -BeNullOrEmpty
        }
        It 'Valid Manifest Description' {
            Test-ModuleManifest -Path .\AKPT.psd1 | Select-Object -ExpandProperty Description | Should -Not -BeNullOrEmpty
        }
        It 'Valid Manifest Root Module' {
            Test-ModuleManifest -Path .\AKPT.psd1 | Select-Object -ExpandProperty RootModule | Should -Be 'AKPT.psm1'
        }
        It 'Valid Manifest GUID' {
            Test-ModuleManifest -Path .\AKPT.psd1 | Select-Object -ExpandProperty Guid | Should -Be 'a0937110-6265-4dff-b670-1b319edeebad'
        }
        It 'Format File' {
            Test-ModuleManifest -Path .\AKPT.psd1 | Select-Object -ExpandProperty ExportedFormatFiles | Should -BeLikeExactly '*\Get-ParameterInfo.format.ps1xml'
        }
    }

    Context 'Exported Functions' {

        BeforeAll {
            Import-Module -Name "$PSCommandPath\..\..\..\..\AKPT"
            $Script:Manifest = Test-ModuleManifest -Path "$PSCommandPath\..\..\..\AKPT.psd1"
        }

        AfterAll {
            Remove-Module -Name 'AKPT'
        }

        $testCases = Get-ChildItem -Path "$PSCommandPath\..\..\..\Public\*.ps1" | Select-Object -ExpandProperty Name | Foreach-Object -Process {@{FunctionName = $_.Replace('.ps1', '')}}

        It "Function <FunctionName> should be in manifest" -TestCases $testCases {
            $ManifestFunctions = Test-ModuleManifest -Path "$PSCommandPath\..\..\..\AKPT.psd1" | Select-Object -ExpandProperty ExportedFunctions | Select-Object -ExpandProperty Keys
            $FunctionName -in $ManifestFunctions | Should -Be $true
        }

        It 'Richtige Anzahl der exportierten Funktionen im Vergleich zum Manifest' {
            $ExportedCount = Get-Command -Module 'AKPT' -CommandType Function | Measure-Object | Select-Object -ExpandProperty Count
            $ManifestCount = ($Manifest.ExportedFunctions.Count + 1) # Wegen function pompt

            $ExportedCount | Should -Be $ManifestCount
        }

        It 'Proper Number of Functions Exported compared to Files' {
            $ExportedCount = Get-Command -Module 'AKPT' -CommandType Function | Where-Object -Property Name -NE "prompt" | Measure-Object | Select-Object -ExpandProperty Count
            $FileCount = Get-ChildItem -Path "$PSCommandPath\..\..\..\Public\*.ps1" | Measure-Object | Select-Object -ExpandProperty Count

            $ExportedCount | Should -Be $FileCount
        }
    }

    AfterAll {
        "TODO Code-Abdeckungs-Analyse implementieren." | Write-Warning
        Invoke-ScriptAnalyzer -Path '.\Public\*.ps1' -Severity Error, Warning, Information, ParseError | ForEach-Object -Process {"REGEL-VERLETZUNG IN {0,-30} ZEILE {1,5} NAME {2}" -f $_.ScriptName, $_.Line, $_.RuleName | Write-Warning }
    }
}