Tests/GenXdev.Helpers/ConvertTo-LLMOpenAIApiFunctionDefinition.Tests.ps1
|
Pester\Describe 'ConvertTo-LLMOpenAIApiFunctionDefinition' { Pester\It 'Should check my sanity' { $number = 123; $callback = { param($a, $b, $c) return (@($a, $b, $c, $number) | Microsoft.PowerShell.Utility\ConvertTo-Json -Compress -WarningAction SilentlyContinue) }.GetNewClosure(); $callback.getType().FullName | Pester\Should -BeExactly 'System.Management.Automation.ScriptBlock' $params = @{ c = 3 a = 1 } $params.getType().FullName | Pester\Should -BeExactly 'System.Collections.Hashtable' $result = & $callback @params $result | Pester\Should -Be (@(1, $null, 3, $number) | Microsoft.PowerShell.Utility\ConvertTo-Json -Compress -WarningAction SilentlyContinue) } Pester\It 'Should invoke function properly' { $converted = GenXdev\ConvertTo-LLMOpenAIApiFunctionDefinition ` -ExposedCmdLets @( @{ Name = 'Get-ChildItem' AllowedParams = @('Path=string') Confirm = $false } ) $functionDefinition = $converted.function $functionDefinition | Pester\Should -Not -Be $null $callback = $functionDefinition.callback; $callback | Pester\Should -BeOfType [System.Management.Automation.CommandInfo] # Convert dictionary to proper parameter hashtable $params = @{'Path' = "$PSScriptRoot" } Microsoft.PowerShell.Utility\Write-Verbose "Final parameter hashtable: $($params | Microsoft.PowerShell.Utility\ConvertTo-Json -WarningAction SilentlyContinue)" # Use $functionDefinition instead of undefined $matchedFunc $callbackResult = & $callback @params | Microsoft.PowerShell.Utility\ConvertTo-Json -Compress -WarningAction SilentlyContinue $callbackResult | Pester\Should -BeLike '*ConvertTo-LLMOpenAIApiFunctionDefinition.Tests.ps1*' } Pester\Context 'Parameter alias matching' { Pester\It 'Should match AllowedParams by parameter alias (Get-ChildItem PSPath)' { # Get-ChildItem -Path has alias 'PSPath' $converted = GenXdev\ConvertTo-LLMOpenAIApiFunctionDefinition ` -ExposedCmdLets @( @{ Name = 'Get-ChildItem' AllowedParams = @('PSPath=string') Confirm = $false } ) $funcDef = $converted.function $funcDef | Pester\Should -Not -Be $null # The parameters property should use the real parameter name # 'LiteralPath', not the alias 'PSPath'. # (Both Path and LiteralPath share the PSPath alias; # Get-CmdletMetaData returns LiteralPath first.) $props = $funcDef.parameters.properties $props | Pester\Should -Not -Be $null $props.Keys | Pester\Should -Not -Contain 'PSPath' # 'LiteralPath' matches first; 'Path' is also valid ($props.Keys -contains 'Path' -or $props.Keys -contains 'LiteralPath') | Pester\Should -BeTrue $props.LiteralPath.type | Pester\Should -Be 'array' $props.LiteralPath.items.type | Pester\Should -Be 'string' } Pester\It 'Should match Find-Item AllowedParams by alias (SearchMask, Pattern)' { # Exact definition from New-LLMTextChat (llmchat) # SearchMask -> Name parameter alias # Pattern -> Content parameter alias $converted = GenXdev\ConvertTo-LLMOpenAIApiFunctionDefinition ` -ExposedCmdLets @( @{ Name = 'GenXdev\Find-Item' AllowedParams = @('SearchMask', 'Pattern') OutputText = $false Confirm = $false JsonDepth = 3 } ) $funcDef = $converted.function $funcDef | Pester\Should -Not -Be $null # Verify top-level structure (type is at outer level, not # inside the 'function' sub-hashtable) $converted.type | Pester\Should -Be 'function' $funcDef.name | Pester\Should -Be 'Find-Item' $funcDef.description | Pester\Should -Not -BeNullOrEmpty # Verify parameters structure $params = $funcDef.parameters $params.type | Pester\Should -Be 'object' # Properties should NOT be empty (regression test for alias bug) $props = $params.properties $props | Pester\Should -Not -Be $null $props | Pester\Should -BeOfType [System.Collections.Hashtable] $props.Count | Pester\Should -BeGreaterThan 0 # SearchMask alias -> Name parameter $props.Keys | Pester\Should -Contain 'Name' $props.Name.type | Pester\Should -Be 'array' $props.Name.items.type | Pester\Should -Be 'string' # Pattern alias -> Content parameter $props.Keys | Pester\Should -Contain 'Content' $props.Content.type | Pester\Should -Be 'array' $props.Content.items.type | Pester\Should -Be 'string' # Callback should be present (CommandInfo) $funcDef.callback | Pester\Should -BeOfType ` [System.Management.Automation.CommandInfo] # Required list should be empty (both params are non-mandatory) $params.required.Count | Pester\Should -Be 0 } Pester\It 'Should produce non-empty properties when matching by alias' { # Regression test: before the alias fix, AllowedParams # using aliases would produce empty properties: {} $converted = GenXdev\ConvertTo-LLMOpenAIApiFunctionDefinition ` -ExposedCmdLets @( @{ Name = 'Get-ChildItem' AllowedParams = @('PSPath=string') Confirm = $false } ) $props = $converted.function.parameters.properties $props.Count | Pester\Should -BeGreaterThan 0 } } } |