Tests/PSDataKit.Tests.ps1

$ModuleManifestName = 'PSDataKit.psd1'
$ModuleManifestPath = "$PSScriptRoot\..\$ModuleManifestName"
Remove-Module "PSDataKit" -Force -ErrorAction Ignore
Import-Module -Name $ModuleManifestPath -Force
Write-Host "Remove and Import PSDataKit module"

Describe 'Module Manifest Tests' {
    It 'Passes Test-ModuleManifest' {
        Test-ModuleManifest -Path $ModuleManifestPath | Should Not BeNullOrEmpty
        $? | Should Be $true
    }
}

InModuleScope PSDataKit {
    Describe 'PSDataKit merging capabilities (Merge-Hashtables)' {

        Context "secondary parameter" {
            It 'Merge with $null secondary parameter ' {
                $primary = @{
                    foo = "foo"
                    bar = "bar"
                }
                $secondary = $null

                $result = Merge-Hashtables -primary $primary -secondary $secondary

                $result | Should -BeExactly $primary
            }
            It 'Merge with BeNullOrEmpty values inside secondary parameter ' {

                $primary = @{
                    nullValue      = "nullValue"
                    emptyValue     = "emptyValue"
                    emptyArray     = "emptyArray"
                    emptyHashtable = "emptyHashtable"
                }
                $secondary = @{
                    emptyValue     = ""
                    nullValue      = $null
                    emptyArray     = @()
                    emptyHashtable = @{ }
                }

                $result = Merge-Hashtables -primary $primary -secondary $secondary

                $result.nullValue | Should -Be $primary.nullValue
                $result.emptyValue | Should -Be $primary.emptyValue
                $result.emptyArray | Should -Be $primary.emptyArray
                $result.emptyHashtable | Should -Be $primary.emptyHashtable
                $result.Test | Should -Be $primary.Test
            }

            It 'Merge with BeNullOrEmpty values inside secondary parameter when primary is hashtable' {

                $primary = @{
                    foo = @{
                        bar = "bar"
                    }
                }
                $secondary = @{
                    foo = $null
                }

                $result = Merge-Hashtables -primary $primary -secondary $secondary
                $result.foo | Should -Be $primary.foo
            }

            It "Merge and does not alter the input parameters" {
                $primary = @{
                    Key1 = @{
                        test = "IsThere"
                    }
                    Key2 = @{
                        test = "IsThere"
                    }
                }
                $secondary = @{
                    Key1 = @{
                        test = "Will be lost"
                        remain = "Will remain"
                    }
                    Key3 = "Will be added"
                }

                $primaryBefore = $primary.Clone()
                $secondaryBefore = $secondary.Clone()

                $expectedResults = @{
                    Key1 = @{
                        test = "IsThere"
                        remain = "Will remain"
                    }
                    Key2 = @{
                        test = "IsThere"
                    }
                    Key3 = "Will be added"
                }

                $result = Merge-Hashtables -primary $primary -secondary $secondary
                ($result | ConvertTo-Json) | Should -Be ( $expectedResults | ConvertTo-Json)
                ($primary | ConvertTo-Json) | Should -Be ($primaryBefore | ConvertTo-Json)
                ($secondary | ConvertTo-Json) | Should -Be ($secondaryBefore | ConvertTo-Json )
            }
        }

    }
    Describe 'Get-OrElse' {

        $mockedEmptyArray = @()
        $mockedSampleArray = @(1,2,3,2,1)
        $mockedEmptyHashTable = @{}
        $mockedSampleHashTable = @{a = 1; b = "2"}
        $mockedEmptyObject = New-Object -TypeName psobject
        $mockedSampleObject = New-Object -TypeName psobject
        $mockedSampleObject | Add-Member -MemberType NoteProperty -Name "UserName" -Value "SampleName"


        Context 'with pipelined value' {

            It 'returns default if value is null' {
                Get-OrElse $Null "default" | Should Be "default"
            }
            It 'returns default if value is empty' {
                Get-OrElse "" "default" | Should Be "default"
            }
            It 'returns value if value is neither null or empty' {
                Get-OrElse "a" "default" | Should Be "a"
                Get-OrElse 1   "default" | Should Be 1
                Get-OrElse " " "default" | Should Be " "
            }
        }
        Context 'with pipeline value' {
            It 'returns default if value is null' {
                $Null | Get-OrElse -Default "default" | Should Be "default"
            }
            It 'returns default if value is empty' {
                "" | Get-OrElse -Default "default" | Should Be "default"
            }
            It 'returns value if value is neither null or empty' {
                "a" | Get-OrElse -Default "default" | Should Be "a"
                1   | Get-OrElse -Default "default" | Should Be 1
                " " | Get-OrElse -Default "default" | Should Be " "
            }
        }
        Context 'with pipeline objects' {
            It 'should return default if array is empty' {
                $mockedEmptyArray | Get-OrElse -Default "default" | Should Be "default"
            }
            It 'should return default if hashtable is empty' {
                $mockedEmptyHashTable | Get-OrElse -Default "default" | Should Be "default"
            }
            It 'should return object if object not empty' {
                $mockedSampleObject | Get-OrElse -Default "default" | Should Be $mockedSampleObject
            }
            It 'should return object if new object PSObject initialized but without members' {
                $mockedEmptyObject | Get-OrElse -Default "default" | Should Be $mockedEmptyObject
            }
        }
        Context 'with parametrized value'{
            It 'should return provided hashmap' {
                Get-OrElse -Value $mockedSampleHashTable -Default "default" | Should Be $mockedSampleHashTable
            }
            It 'should return provided array' {
                Get-OrElse -Value $mockedSampleArray -Default "default" | Should Be $mockedSampleArray
            }
        }
    }
}