diff --git a/lib/ansible/module_utils/csharp/Ansible.Basic.cs b/lib/ansible/module_utils/csharp/Ansible.Basic.cs index 845d25eeb4..00b4096d5b 100644 --- a/lib/ansible/module_utils/csharp/Ansible.Basic.cs +++ b/lib/ansible/module_utils/csharp/Ansible.Basic.cs @@ -1039,13 +1039,26 @@ namespace Ansible.Basic private void CheckSubOption(IDictionary param, string key, IDictionary spec) { + object value = param[key]; + string type; if (spec["type"].GetType() == typeof(string)) type = (string)spec["type"]; else type = "delegate"; - string elements = (string)spec["elements"]; - object value = param[key]; + + string elements = null; + Delegate typeConverter = null; + if (spec["elements"] != null && spec["elements"].GetType() == typeof(string)) + { + elements = (string)spec["elements"]; + typeConverter = optionTypes[elements]; + } + else if (spec["elements"] != null) + { + elements = "delegate"; + typeConverter = (Delegate)spec["elements"]; + } if (!(type == "dict" || (type == "list" && elements != null))) // either not a dict, or list with the elements set, so continue @@ -1057,7 +1070,6 @@ namespace Ansible.Basic return; List newValue = new List(); - Delegate typeConverter = optionTypes[elements]; foreach (object element in (List)value) { if (elements == "dict") diff --git a/test/integration/targets/win_csharp_utils/library/ansible_basic_tests.ps1 b/test/integration/targets/win_csharp_utils/library/ansible_basic_tests.ps1 index d57f2128ad..124c87c180 100644 --- a/test/integration/targets/win_csharp_utils/library/ansible_basic_tests.ps1 +++ b/test/integration/targets/win_csharp_utils/library/ansible_basic_tests.ps1 @@ -503,6 +503,47 @@ $tests = @{ $actual.invocation | Assert-DictionaryEquals -Expected @{module_args = $expected_module_args} } + "Parse module args with list elements and delegate type" = { + $spec = @{ + options = @{ + list_delegate_type = @{ + type = "list" + elements = [Func[[Object], [UInt16]]]{ [System.UInt16]::Parse($args[0]) } + } + } + } + $complex_args = @{ + list_delegate_type = @( + "1234", + 4321 + ) + } + $m = [Ansible.Basic.AnsibleModule]::Create(@(), $spec) + $m.Params.list_delegate_type.GetType().Name | Assert-Equals -Expected 'List`1' + $m.Params.list_delegate_type[0].GetType().FullName | Assert-Equals -Expected "System.UInt16" + $m.Params.list_delegate_Type[1].GetType().FullName | Assert-Equals -Expected "System.UInt16" + + $failed = $false + try { + $m.ExitJson() + } catch [System.Management.Automation.RuntimeException] { + $failed = $true + $_.Exception.Message | Assert-Equals -Expected "exit: 0" + $actual = [Ansible.Basic.AnsibleModule]::FromJson($_test_out) + } + $failed | Assert-Equals -Expected $true + + $expected_module_args = @{ + list_delegate_type = @( + 1234, + 4321 + ) + } + $actual.Keys.Count | Assert-Equals -Expected 2 + $actual.changed | Assert-Equals -Expected $false + $actual.invocation | Assert-DictionaryEquals -Expected @{module_args = $expected_module_args} + } + "Parse module args with case insensitive input" = { $spec = @{ options = @{