Describe "Dynamic parameter support in script cmdlets." -Tags "CI" {
    BeforeAll {
        Class MyTestParameter {
            [parameter(ParameterSetName = 'pset1', position=0, mandatory=1)]
            [string] $name
        }

        function foo-bar
        {
            [CmdletBinding()]
            param($path)

            dynamicparam {
                if ($PSBoundParameters["path"] -contains "abc") {
                    $attributes = [System.Management.Automation.ParameterAttribute]::New()
                    $attributes.ParameterSetName = 'pset1'
                    $attributes.Mandatory = $false

                    $attributeCollection = [System.Collections.ObjectModel.Collection``1[System.Attribute]]::new()
                    $attributeCollection.Add($attributes)

                    $dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new("dp1", [Int32], $attributeCollection)

                    $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
                    $paramDictionary.Add("dp1", $dynParam1)

                    return $paramDictionary
                }
                elseif($PSBoundParameters["path"] -contains "class") {
                    $paramDictionary = [MyTestParameter]::new()
                    return $paramDictionary
                }

                $paramDictionary = $null
                return $null
            }

            begin {
                if(($null -ne $paramDictionary) -and ($paramDictionary -is [MyTestParameter]) ) {
                    $paramDictionary.name
                }
                elseif ($null -ne $paramDictionary) {
                    if ($null -ne $paramDictionary.dp1.Value) {
                        $paramDictionary.dp1.Value
                    }
                    else {
                        "dynamic parameters not passed"
                    }
                }
                else {
                  "no dynamic parameters"
                }
            }

            process {}
            end {}
        }
    }

    It "The dynamic parameter is enabled and bound" {
        foo-bar -path abc -dp1 42 | Should Be 42
    }

    It "When the dynamic parameter is not available, and raises an error when specified" {
        try {
            foo-bar -path def -dp1 42
            Throw "Exception expected, execution should not have reached here"
        } catch {
            $_.FullyQualifiedErrorId | Should Be "NamedParameterNotFound,foo-bar"
        }
    }

    It "No dynamic parameter shouldn't cause an errr " {
        foo-bar -path def  | Should Be 'no dynamic parameters'
    }

    It "Not specifying dynamic parameter shouldn't cause an error" {
        foo-bar -path abc | Should Be 'dynamic parameters not passed'
    }

    It "Parameter is defined in Class" {
        foo-bar -path class -name "myName" | Should Be 'myName'
    }
}
