functions/_Set-VariableFromEnvVar.Tests.ps1

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"

Describe "Set-VariableFromEnvVar Tests" {

    Context "String values" {

        Describe "When overriding an existing variable" {

            Mock Set-Variable {} -ParameterFilter { $Scope -eq "script" -and $Name -eq "someString" -and $Value -eq "bar" }

            $script:someString = "foo"
            $env:newValueForSomeString = "bar"
            $res = Set-VariableFromEnvVar -VariableName "someString" -EnvironmentVariableName "newValueForSomeString"

            It "should return true" {
                $res | Should -Be $true
            }
            It "should correctly update the variable's value" {
                Assert-MockCalled Set-Variable -Times 1
            }
        }

        Describe "When overriding an existing variable that is null" {

            Mock Set-Variable {} -ParameterFilter { $Scope -eq "script" -and $Name -eq "nullVar" -and $Value -eq "foo" }

            $script:nullVar = $null
            $env:newValueForNullVar = "foo"
            $res = Set-VariableFromEnvVar -VariableName "nullVar" -EnvironmentVariableName "newValueForNullVar"

            It "should return true" {
                $res | Should -Be $true
            }
            It "should correctly update the variable's value" {
                Assert-MockCalled Set-Variable -Times 1
            }

        }
    }

    Context "Integer values" {

        Describe "When overriding an existing variable" {

            Mock Set-Variable {} -ParameterFilter { $Scope -eq "script" -and $Name -eq "someNum" -and $Value -eq 5 }

            $script:someNum = 1
            $env:newValueForsomeNum = "5"
            $res = Set-VariableFromEnvVar -VariableName "someNum" -EnvironmentVariableName "newValueForsomeNum"

            It "should return true" {
                $res | Should -Be $true
            }
            It "should correctly update the variable's value" {
                Assert-MockCalled Set-Variable -Times 1
            }
        }
    }

    Context "Boolean values" {

        Describe "When overriding an existing variable" {

            Mock Set-Variable {} -ParameterFilter { $Scope -eq "script" -and $Name -eq "someFlag" -and $Value -eq $true }

            $script:someFlag = $false
            $env:newValueForSomeFlag = "True"
            $res = Set-VariableFromEnvVar -VariableName "someFlag" -EnvironmentVariableName "newValueForSomeFlag"

            It "should return true" {
                $res | Should -Be $true
            }
            It "should correctly update the variable's value" {
                Assert-MockCalled Set-Variable -Times 1
            }
        }
    }

    Context "Hashtable values" {

        Describe "When overriding an existing variable with a valid JSON object" {

            Mock Set-Variable {} -ParameterFilter { $Scope -eq "script" -and $Name -eq "someDictionary" -and $Value["foo"] -eq "foo" -and $Value["bar"] -eq "bar" }

            $script:someDictionary = @{foo="bar"; bar="foo"}
            $env:newValueForsomeDictionary = '{"foo": "foo", "bar": "bar"}'
            $res = Set-VariableFromEnvVar -VariableName "someDictionary" -EnvironmentVariableName "newValueForsomeDictionary"

            It "should return true" {
                $res | Should -Be $true
            }
            It "should correctly update the variable's value" {
                Assert-MockCalled Set-Variable -Times 1
            }
        }

        Describe "When overriding an existing variable with invalid JSON" {

            Mock Set-Variable {} -ParameterFilter { $Name -eq "someDictionary" -and $Value -eq @{foo="foo"; bar="bar"} }
            Mock Write-Warning {}

            $script:someDictionary = @{foo="bar"; bar="foo"}
            $env:newValueForsomeDictionary = '{"foo"="foo", "bar"="bar"}'
            $res = Set-VariableFromEnvVar -VariableName "someDictionary" -EnvironmentVariableName "newValueForsomeDictionary"

            It "should return false" {
                $res | Should -Be $false
            }
            It "should not update the variable's value" {
                Assert-MockCalled Set-Variable -Times 0
            }
            It "should log a warning" {
                Assert-MockCalled Write-Warning -Times 1
            }
        }
    }
}