JBOADS.Module.Tests.ps1

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$module = "JBOADS"

Describe -Tags ('Unit', 'Acceptance') "$module Module Tests" {

    Context 'Module Setup' {
        It "has the root module $module.psm1" {
            "$here\$module.psm1" | Should -Exist
        }

        It "has the a manifest file of $module.psd1" {
            "$here\$module.psd1" | Should -Exist
            "$here\$module.psd1" | Should -FileContentMatch "$module.psd1"
        }

        It "has a Public folder" {
            "$here\Public" | Should -Exist
        }

        It "$module\Public folder has functions" {
            "$here\Public\*.ps1" | Should -Exist
        }

        It "has a Private folder" {
            "$here\Private" | Should -Exist
        }

        It "has a Bin folder" {
            "$here\Bin" | Should -Exist
        }

        It "has a en-Us folder" {
            "$here\en-Us" | Should -Exist
        }

        It "has a Lib folder" {
            "$here\Lib" | Should -Exist
        }

        It "has a $module.Format.ps1xml file" {
            "$here\$module.Format.ps1xml" | Should -Exist
        }

        It "has a $module.Types.ps1xml file" {
            "$here\$module.Types.ps1xml" | Should -Exist
        }

        It "$module is valid PowerShell code" {
            $psFile = Get-Content -Path "$here\$module.psm1" -ErrorAction Stop
            $errors = $null
            $null = [System.Management.Automation.PSParser]::Tokenize($psFile, [ref]$errors)
            $errors.Count | Should -Be 0
        }
    } # Context 'Module Setup'

    $publicfunctionfiles = (Get-ChildItem $here\Public\).Name
    $publicfunctions = @()
    foreach ($function in $publicfunctionfiles) {
        $pos = $function.IndexOf(".")
        $publicfunction = $function.SubString(0, $pos)
        $publicfunctions += $publicfunction
    }

    foreach ($function in $PublicFunctions) {

        Context "Test Function $function" {

            It "$function.ps1 should exist" {
                "$here\Public\$function.ps1" | Should -Exist
            }

            It "$function.ps1 should have help block" {
                "$here\Public\$function.ps1" | Should -FileContentMatch '<#'
                "$here\Public\$function.ps1" | Should -FileContentMatch '#>'
            }

            It "$function.ps1 should have a SYNOPSIS section in the help block" {
                "$here\Public\$function.ps1" | Should -FileContentMatch '.SYNOPSIS'
            }

            It "$function.ps1 should have a usefull SYNOPSIS section in the help block" {
                "$here\Public\$function.ps1" | Should -Not -FileContentMatch 'Short description'
            }

            It "$function.ps1 should have a DESCRIPTION section in the help block" {
                "$here\Public\$function.ps1" | Should -FileContentMatch '.DESCRIPTION'
            }

            It "$function.ps1 should have a usefull DESCRIPTION section in the help block" {
                "$here\Public\$function.ps1" | Should -Not -FileContentMatch 'Long description'
            }

            It "$function.ps1 should have a usefull PARAMETER section in the help block" {
                "$here\Public\$function.ps1" | Should -Not -FileContentMatch 'The description of the Param1 parameter.'
            }

            It "$function.ps1 should have a EXAMPLE section in the help block" {
                "$here\Public\$function.ps1" | Should -FileContentMatch '.EXAMPLE'
            }

            It "$function.ps1 should have a usefull EXAMPLE section in the help block" {
                "$here\Public\$function.ps1" | Should -Not -FileContentMatch 'Example of how to use this cmdlet'
            }

            It "$function.ps1 should be an advanced function" {
                "$here\Public\$function.ps1" | Should -FileContentMatch 'function'
                "$here\Public\$function.ps1" | Should -FileContentMatch 'cmdletbinding'
                "$here\Public\$function.ps1" | Should -FileContentMatch 'param'
            }

            It "$function.ps1 should have an OutputType defined" {
                "$here\Public\$function.ps1" | Should -FileContentMatch '.Outputs || OutputType'
            }

            It "$function.ps1 should have usefull helpmessages for in the param block" {
                "$here\Public\$function.ps1" | Should -Not -FileContentMatch "Help message for this parameter"
            }

            #It "$function.ps1 should contain Write-Verbose blocks" {
            # "$here\Public\$function.ps1" | Should -FileContentMatch 'Write-Verbose'
            #}

            It "$function.ps1 is valid PowerShell code" {
                $psFile = Get-Content -Path "$here\Public\$function.ps1" -ErrorAction Stop
                $errors = $null
                $null = [System.Management.Automation.PSParser]::Tokenize($psFile, [ref]$errors)
                $errors.Count | Should -Be 0
            }

        } # Context "Test Function $function"

        Context "$function has tests" {
            It "$($function).Tests.ps1 should exist" {
                "$here\Tests\$($function).Tests.ps1" | Should -Exist
            }
        } # foreach ($function in $PublicFunctions)
    }
}