Private/Tests/AKPT.Tests.ps1

# ? TITEL UTest AKPT Module
# ? DESCRIPTION Pester UTest für diese Module AKPT.
# ? TAGS UTest Pester Module
# ? VERSION 2020.01.13

using Module  CimCmdlets
using Module  Microsoft.PowerShell.Management
using Module  Microsoft.PowerShell.Security
using Module  Microsoft.PowerShell.Utility
using Module  Microsoft.WSMan.Management
using Module  Pester
using Module  PSScriptAnalyzer

using namespace System
using namespace System.Management.Automation

$ErrorActionPreference = [ActionPreference]::Stop

Set-StrictMode -Version Latest

$modulePath = Split-Path -Path $MyInvocation.MyCommand.Path | Split-Path | Split-Path
$moduleName = Split-Path -Path $MyInvocation.MyCommand.Path | Split-Path | Split-Path | Split-Path -Leaf
$moduleManifest = Resolve-Path -Path "$modulePath\$moduleName.psd1" | Select-Object -ExpandProperty Path

Describe "Module $moduleName" -Tag 'Compliance' {
    
    # Context 'Public\Content.ps1 Tests' {
    # "An dieser stelle die einzelen tests aufrufen" | Write-Warning
    # "implement Code Coverage" | Write-Warning
    # # Invoke-Pester -Script
    # }

    Context 'Basic Module Testing' {
        $scripts = Get-ChildItem "$modulePath\Public" -Include *.ps1, *.psm1, *.psd1 -Recurse
        $testCase = $scripts | Foreach-Object {
            @{
                FilePath = $_.FullName
                FileName = $_.Name
            }
        }
        
        It "Script <FileName> should be valid powershell" -TestCases $testCase {
            param( $FilePath, $FileName )

            $FilePath | Should Exist

            $contents = Get-Content -Path $FilePath -ErrorAction Stop
            $errors = $null
            $null = [System.Management.Automation.PSParser]::Tokenize($contents, [ref]$errors)
            $errors.Count | Should Be 0
        }

        It "Modul '$moduleName' problemlos importiert" {
            { Import-Module -Name $ModuleManifest -Force } | Should Not Throw
        }
        
        It "Module '$moduleName' problemlos entladen" {
            { Remove-Module -Name $moduleName -Force } | Should Not Throw
        }
    }
    
    Context 'Manifest Testing' {
        
        It 'Valid Module Manifest' {
            {
                $Script:Manifest = Test-ModuleManifest -Path $ModuleManifest -ErrorAction Stop -WarningAction SilentlyContinue
            } | Should Not Throw
        }
        It 'Valid Manifest Name' {
            $Script:Manifest.Name | Should be $ModuleName
        }
        It 'Generic Version Check' {
            $Script:Manifest.Version -as [Version] | Should Not BeNullOrEmpty
        }
        It 'Valid Manifest Description' {
            $Script:Manifest.Description | Should Not BeNullOrEmpty
        }
        It 'Valid Manifest Root Module' {
            $Script:Manifest.RootModule | Should Be "$ModuleName.psm1"
        }
        It 'Valid Manifest GUID' {
            $Script:Manifest.Guid | Should be 'a0937110-6265-4dff-b670-1b319edeebad'
        }
        It 'No Format File' {
            $Script:Manifest.ExportedFormatFiles | Should BeNullOrEmpty
        }
    }

    Import-Module -Name $ModuleManifest -Force

    Context 'Exported Functions' {

        $ExportedFunctions = (Get-ChildItem -Path "$modulePath\Public\*.ps1" -Exclude *.Tests.ps1 | Select-Object -ExpandProperty Name) -replace '\.ps1$'
        $testCase = $ExportedFunctions | Foreach-Object -Process {@{FunctionName = $_}}
        
        It "Function <FunctionName> should be in manifest" -TestCases $testCase {
            param($FunctionName)
            $ManifestFunctions = $Manifest.ExportedFunctions.Keys
            $FunctionName -in $ManifestFunctions | Should Be $true
        }
    
        It 'Richtige Anzahl der exportierten Funktionen im Vergleich zum Manifest' {
            $ExportedCount = Get-Command -Module $ModuleName -CommandType Function | Measure-Object | Select-Object -ExpandProperty Count
            $ManifestCount = $Manifest.ExportedFunctions.Count

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

    Context 'Exported Aliases' {
        It 'Richtige Anzahl der exportierten Aliase im Vergleich zum Manifest' {
            $ExportedCount = Get-Command -Module $ModuleName -CommandType Alias | Measure-Object | Select-Object -ExpandProperty Count
            $ManifestCount = $Manifest.ExportedAliases.Count
    
            $ExportedCount | Should be $manifestCount
        }
    
        It 'Richtige Anzahl der exportierten Aliase im Vergleich zu den Cmdlet.ps1-Dateien' {
            $AliasCount    = Get-ChildItem -Path "$modulePath\Public\*.ps1" -Exclude *.Tests.ps1 | Select-String "New-Alias" | Measure-Object | Select-Object -ExpandProperty Count
            $manifestCount = $Manifest.ExportedAliases.Count
    
            $AliasCount  | Should be $manifestCount
        }
    }

    Remove-Module -Name $moduleName -Force
}