Private/BitTitanTools/BitTitanTools.Tests.ps1

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = "$here\BitTitanTools.psm1"

# ^If ever integrated with buildserver, will most likely have to change the above to the corresponding teamcity environment variables

Describe "BitTitanTools" {

    Context "Meta: Verify runtype parameters" {
        It "Should only be tested on powershell versions 3, and above" {
            $PSVersionTable.PSVersion.Major -ge 3 | should Be $true
        }
    }

    Context "Meta: Verify module and exported commands" {
        
        It "Verifies that the import of the parent module" {
            {Import-Module "$sut"} | Should Not Throw
        }
        
        It "Verifies count of exported commands" {
            $commands = (Get-Module BitTitanTools).ExportedCommands.count
            $commands | Should be 17
        }
    
    }

    Context "Tests for 'Set-LoggingConfiguration' function" {
        $script:runtype = 'Debug'
        $script:scriptname = "testingscript"
        $script:testFolder = "test1"
        $script:scriptVersion = 1
        
        It "Verifies that the Set-LogginConfiguration function should not throw" {
            { Set-LoggingConfiguration -RunType "$script:runtype" -ScriptName "$script:scriptname" -LogToConsole -LogFolder "$here\$script:testFolder" -ScriptVersion $script:scriptVersion } |
            Should Not Throw
        }

        It "Verifies that the function will not throw an exception if a non-existent loggin directory is specified" {
            { Set-LoggingConfiguration -RunType "$script:runtype" -ScriptName "$script:scriptname" -LogToConsole -LogFolder "$here\$script:testFolder" -ScriptVersion $script:scriptVersion } |
            Should Not Throw
        }

        It "Verifies that the folder above exists" {
            (Get-Item "$here\$script:testFolder").Name | should match "$script:testFolder"
        }

        It "Verifies the 'runtype' global variable" {
            $Global:RunType | Should Match $script:runtype
        }
        
        It "Verifies the 'scriptname' global variable" {    
            $Global:ScriptName | Should match $script:scriptname
        }
    
        It "Verifies the 'LogToConsole' global variable" {
            $Global:LogToConsole | Should Be True
        }

        It "Verifies the 'ScriptVersion' global variable" {
            $Global:ScriptVersion | Should match $script:scriptVersion
        }
    }

    Context "Tests for 'Get-LoggingConfiguration' function" {
        $logConfig = Get-LoggingConfiguration
        
        It "Will return a date type of 'hashtable'" {
            $logConfig | Should BeOfType [System.Collections.Hashtable]
        }
    }

    Context "Tests for 'Add-LogEntry' function" {
        $messageDateTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        $fileDateTime = Get-Date -Format "yyyy_MM-dd_"
        # !!! Can't match the HH, mm and ss's of the datetime format, since all are likely to change durring a given job's run -- so only the year, month and date will be matched -- followed by a wildcard.
        $logFileformat = "$ScriptName-$script:ScriptVersion-$RunType-$fileDateTime"
        $logMessageformat = "$ScriptName.$RunType.$MessagedateTime"
        $testmessage = "yo ho yo ho, a pirate's life for me"
        Add-LogEntry -Message $testmessage
        # Since we're now using a nested path structure, ensure to write a message before hand to be able to recursively sift through the current directory and parse for a '*txt' extension
        $logfile = Get-ChildItem $here -Recurse -Filter "*.txt"
        # A little logic to ensure that we can programatically determine the correct log to write to, otherwise break and instruct operator to delete the staging directory (should happen after each test anyway)
        if ($logfile.count -gt 1) {
            Write-Warning "More than one log-file found in staging directory ' $script:testfolder ' -- can not determine desired log file destination"
            Write-Warning "Delete the staging directory ' $script:testfolder '...breaking"
            break
        }
        else {
            $logfile = $logfile.FullName.ToString()
            Write-Host -ForegroundColor Green "Using following log file for testing ' $logfile ' "
        }
        
        It "Should verify that an exception is not thrown when calling the Add-LogEntry function" {
            { Add-LogEntry -Message $testmessage} | Should Not Throw
        }
        
        
        It "Should verify that a test message was written to the log file" {
            "$logfile" | should contain $testmessage
        }

        It "Should observe the correct logging format <scriptname>.<runtype>.<datetime:'yyyy-MM-dd HH:mm:ss'>" {
            "$logfile*" | should contain $logMessageformat
        }

        It "Should observe the correct naming convention" {
        # !!! Only matching the filename up to the date (not including hour, minute and seconds) of the string -- as hour, minute and second are going to change during the script's run
            (Get-ChildItem "$logfile").FullName.ToString() | should match $logFileformat*
        }
    
    }

    Context "Tests for 'Suspend-Logging' function" {
     # Just need to verify that the 'suspendLogging' global is returned
        Suspend-Logging
        It "Should return a global variable called 'SuspendLogging', with the value of True" {
            $Global:SuspendLogging | Should Be $true    
        }
    }

    Context "Tests for ' Resume-Logging ' function" {
        Resume-Logging
        It "Should set the global varaible 'SuspendLogging' to False'" {
            $Global:SuspendLogging | Should Be $false
        }
    }

} # End Describe Block

#### Cleanup
# Ensure that the $testfolder isn't null before trying to delete it...otherwise it'll delete the parent directory :(
# ...also necesssary since we can't predict logfile names (nested paths with datetime (including HH,mm and ss) in the string -- so we have to blow the logging directory away after each run
# ...to ensure that only one .txt file exists currently.
if (($script:testfolder -ne $null)) {
    Write-Warning "Cleaning up testing folder/files(s) from $here\$script:testfolder"
    Remove-Item -Path "$here\$script:testfolder" -Recurse -Verbose -Force
}
else {
    Write-Warning "Test folder was null, skipping cleanup"
}