diff --git a/src/Common/YamlUtils.cs b/src/Common/YamlUtils.cs index 3e7a0bda..950cc1ff 100644 --- a/src/Common/YamlUtils.cs +++ b/src/Common/YamlUtils.cs @@ -646,8 +646,6 @@ private static List GetSyntaxFromDictionary(OrderedDictionary dictio } } - // add the parameter name - si.Parameters.ForEach(p => si.AddParameter(p)); syntaxes.Add(si); } } diff --git a/src/MamlWriter/DataType.cs b/src/MamlWriter/DataType.cs index c6cccfd3..4d9f36c5 100644 --- a/src/MamlWriter/DataType.cs +++ b/src/MamlWriter/DataType.cs @@ -16,7 +16,7 @@ public class DataType /// /// The data-type name. /// - [XmlElement("name", Namespace = Constants.XmlNamespace.Dev, Order = 0)] + [XmlElement("name", Namespace = Constants.XmlNamespace.MAML, Order = 0)] public string Name { get; set; } = string.Empty; /// diff --git a/src/MamlWriter/MamlHelpers.cs b/src/MamlWriter/MamlHelpers.cs index bc9025d7..5bbc19f2 100644 --- a/src/MamlWriter/MamlHelpers.cs +++ b/src/MamlWriter/MamlHelpers.cs @@ -86,7 +86,7 @@ public static Command ConvertCommandHelpToMamlCommand(CommandHelp commandHelp) { foreach (var syntax in commandHelp.Syntax) { - command.Syntax.Add(ConvertSyntax(syntax)); + command.Syntax.Add(ConvertSyntax(syntax, commandHelp.Parameters)); } } @@ -142,7 +142,7 @@ private static IEnumerable ConvertInputOutput(List parameters) { var newSyntax = new SyntaxItem(); var firstSpace = syntax.CommandName.IndexOf(' '); @@ -154,10 +154,8 @@ private static SyntaxItem ConvertSyntax(Model.SyntaxItem syntax) { newSyntax.CommandName = syntax.CommandName.Substring(0, firstSpace); } - foreach(var parameter in syntax.GetParametersInOrder()) - { - newSyntax.Parameters.Add(ConvertParameter(parameter)); - } + syntax.SortParameters(); + newSyntax.Parameters.AddRange(syntax.SyntaxParameters.Select(sp => ConvertSyntaxParameter(sp, parameters))); return newSyntax; } @@ -169,16 +167,22 @@ private static PipelineInputType GetPipelineInputType(Model.Parameter parameter) return pipelineInput; } - private static ParameterValue GetParameterValue(Model.Parameter parameter) + private static ParameterValue? GetParameterValue(Model.Parameter parameter) { + // dont render element when the parameter type is SwitchParameter + if (parameter.Type is "SwitchParameter" or "System.Management.Automation.SwitchParameter") + { + return null; + } + var parameterValue = new ParameterValue(); if (parameter is not null) { parameterValue.DataType = parameter.Type; parameterValue.IsVariableLength = parameter.VariableLength; - // We just mark mandatory if one of the parameter sets is mandatory since MAML doesn't - // have a way to disambiguate these. - parameterValue.IsMandatory = parameter.ParameterSets.Any(x => x.IsRequired); + // Should be `true`. This indicates not the parameter is mandatory or not, but the parameter **value** is mandatory or not. + // The parameter which parameter value is not required is SwitchParameter, but SwitchParameter does not ouput this element itself. + parameterValue.IsMandatory = true; } return parameterValue; } @@ -192,6 +196,7 @@ private static Parameter ConvertParameter(Model.Parameter parameter) var pSet = parameter.ParameterSets.FirstOrDefault(); newParameter.Position = pSet is null ? Model.Constants.NamedString : pSet.Position; newParameter.Value = GetParameterValue(parameter); + newParameter.Type = new DataType() { Name = parameter.Type }; if (parameter.Description is not null) { @@ -201,6 +206,61 @@ private static Parameter ConvertParameter(Model.Parameter parameter) } } + if (parameter.Aliases.Count > 0) + { + newParameter.Aliases = string.Join(", ", parameter.Aliases); + } + + if (parameter.AcceptedValues.Count > 0) + { + var acceptedValues = parameter.AcceptedValues.Select(val => new ParameterValue() { DataType = val }); + newParameter.ParameterValueGroup = acceptedValues.ToList(); + } + + return newParameter; + } + + private static Parameter ConvertSyntaxParameter(Model.SyntaxParameter syntaxParam, List parameters) + { + var newParameter = new MAML.Parameter() + { + Name = syntaxParam.ParameterName, + IsMandatory = syntaxParam.IsMandatory, + Position = syntaxParam.Position, + }; + if (syntaxParam.IsSwitchParameter) + { + newParameter.Type = new DataType() + { + Name = "System.Management.Automation.SwitchParameter" + }; + } + else + { + newParameter.Value = new MAML.ParameterValue() + { + DataType = syntaxParam.ParameterType, + IsMandatory = true + }; + + var parameter = parameters.FirstOrDefault(p => string.Equals(p.Name, syntaxParam.ParameterName, StringComparison.Ordinal)); + if (parameter is not null) + { + newParameter.Type = new DataType() + { + Name = parameter.Type + }; + if (parameter.Aliases.Count > 0) + { + newParameter.Aliases = string.Join(", ", parameter.Aliases); + } + if (parameter.AcceptedValues.Count > 0) + { + var acceptedValues = parameter.AcceptedValues.Select(val => new ParameterValue() { DataType = val }); + newParameter.ParameterValueGroup = acceptedValues.ToList(); + } + } + } return newParameter; } diff --git a/src/MamlWriter/Parameter.cs b/src/MamlWriter/Parameter.cs index 37a4f287..4027f6c3 100644 --- a/src/MamlWriter/Parameter.cs +++ b/src/MamlWriter/Parameter.cs @@ -25,11 +25,21 @@ public class Parameter [XmlArrayItem("para", Namespace = Constants.XmlNamespace.MAML)] public List Description { get; set; } = new List(); + /// + /// The parameter value group information ("command:parameterValueGroup"). + /// + [XmlArray("parameterValueGroup", Namespace = Constants.XmlNamespace.Command, Order = 2)] + [XmlArrayItem("parameterValue", Namespace = Constants.XmlNamespace.Command)] + public List? ParameterValueGroup { get; set; } + /// /// The parameter value information ("command:parameterValue"). /// - [XmlElement("parameterValue", Namespace = Constants.XmlNamespace.Command, Order = 2)] - public ParameterValue Value { get; set; } = new ParameterValue(); + [XmlElement("parameterValue", Namespace = Constants.XmlNamespace.Command, Order = 3)] + public ParameterValue? Value { get; set; } + + [XmlElement("type", Namespace = Constants.XmlNamespace.Dev, Order = 4)] + public DataType? Type { get; set; } /// /// Is the parameter mandatory? diff --git a/src/MarkdownReader/CommandHelpMarkdownReader.cs b/src/MarkdownReader/CommandHelpMarkdownReader.cs index 5d85e244..b9ff7942 100644 --- a/src/MarkdownReader/CommandHelpMarkdownReader.cs +++ b/src/MarkdownReader/CommandHelpMarkdownReader.cs @@ -256,6 +256,7 @@ internal static CommandHelp GetCommandHelpFromMarkdown(ParsedMarkdownContent mar { syntaxDiagnostics.ForEach(d => commandHelp.Diagnostics.TryAddDiagnostic(d)); } + commandHelp.Syntax.ForEach(si => si.HasCmdletBinding = commandHelp.HasCmdletBinding); List aliasesDiagnostics = new(); bool aliasHeaderFound = false; diff --git a/src/Model/CommandHelp.cs b/src/Model/CommandHelp.cs index 7618e72c..5d527a46 100644 --- a/src/Model/CommandHelp.cs +++ b/src/Model/CommandHelp.cs @@ -202,34 +202,6 @@ internal void AddExampleItemRange(IEnumerable example) internal void AddParameter(Parameter parameter) { Parameters.Add(parameter); - foreach(var parameterSet in parameter.ParameterSets) - { - if (string.Compare(parameterSet.Name, "(All)", StringComparison.OrdinalIgnoreCase) == 0) - { - foreach(var syntax in SyntaxDictionary.Values) - { - try - { - syntax.AddParameter(parameter); - } - catch - { - // This is okay, we just don't want to add it to the syntax item if it's already there. - } - } - } - else if (SyntaxDictionary.TryGetValue(parameterSet.Name, out var syntaxItem)) - { - try - { - syntaxItem.AddParameter(parameter); - } - catch - { - // This is okay, we just don't want to add it to the syntax item if it's already there. - } - } - } } public bool TryGetParameter(string name, out Parameter? parameter) diff --git a/src/Model/SyntaxItem.cs b/src/Model/SyntaxItem.cs index e1741163..2484e83f 100644 --- a/src/Model/SyntaxItem.cs +++ b/src/Model/SyntaxItem.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; using System.Text; @@ -20,27 +19,6 @@ public class SyntaxItem : IEquatable public List SyntaxParameters = new(); - public List Parameters = new(); - - private List _parameterNames = new(); - - public ReadOnlyCollection ParameterNames { - get => new ReadOnlyCollection(_parameterNames); - } - - public ReadOnlyCollection PositionalParameterKeys { - get => new ReadOnlyCollection(_positionalParameters.Keys); - } - - // Sort parameters by position - private SortedList _positionalParameters; - - // Sort parameters by if they are Required by name - private SortedList _requiredParameters; - - // Sort parameters by name - private SortedList _alphabeticOrderParameters; - public bool IsDefaultParameterSet { get; } public SyntaxItem(string commandName, string parameterSetName, bool isDefaultParameterSet) @@ -48,10 +26,6 @@ public SyntaxItem(string commandName, string parameterSetName, bool isDefaultPar CommandName = commandName; ParameterSetName = parameterSetName; IsDefaultParameterSet = isDefaultParameterSet; - - _positionalParameters = new SortedList(); - _requiredParameters = new SortedList(); - _alphabeticOrderParameters = new SortedList(); } /// @@ -65,26 +39,6 @@ public SyntaxItem(SyntaxItem syntaxItem) IsDefaultParameterSet = syntaxItem.IsDefaultParameterSet; SyntaxParameters = new List(syntaxItem.SyntaxParameters); HasCmdletBinding = syntaxItem.HasCmdletBinding; - Parameters = new List(syntaxItem.Parameters); - - _positionalParameters = new SortedList(syntaxItem._positionalParameters); - _requiredParameters = new SortedList(syntaxItem._requiredParameters); - _alphabeticOrderParameters = new SortedList(syntaxItem._alphabeticOrderParameters); - _parameterNames = new List(syntaxItem._parameterNames); - } - - public void AddParameter(Parameter parameter) - { - string name = parameter.Name; - - if (Constants.CommonParametersNames.Contains(name)) - { - HasCmdletBinding = true; - return; - } - - _parameterNames.Add(name); - _alphabeticOrderParameters.Add(name, parameter); } /// @@ -130,19 +84,6 @@ public void SortParameters() SyntaxParameters = sortedList; } - public void AddParameter(SyntaxParameter parameter) - { - string name = parameter.ParameterName; - - if (Constants.CommonParametersNames.Contains(name)) - { - HasCmdletBinding = true; - return; - } - - _parameterNames.Add(name); - } - private string GetFormattedSyntaxParameter(string paramName, string paramTypeName, bool isPositional, bool isRequired) { bool isSwitchParam = string.Equals(paramTypeName, "SwitchParameter", StringComparison.OrdinalIgnoreCase); @@ -183,24 +124,6 @@ private string GetFormattedSyntaxParameter(string paramName, string paramTypeNam } } - public IEnumerable GetParametersInOrder() - { - foreach (KeyValuePair kv in _positionalParameters) - { - yield return kv.Value; - } - - foreach (KeyValuePair kv in _requiredParameters) - { - yield return kv.Value; - } - - foreach (KeyValuePair kv in _alphabeticOrderParameters) - { - yield return kv.Value; - } - } - /// /// This emits the command and parameters as if they were returned by Get-Command -syntax /// diff --git a/src/Transform/TransformBase.cs b/src/Transform/TransformBase.cs index e1fa9b78..78df4642 100644 --- a/src/Transform/TransformBase.cs +++ b/src/Transform/TransformBase.cs @@ -376,8 +376,6 @@ protected IEnumerable GetSyntaxItem(CommandInfo? cmdletInfo, dynamic string.Compare(paramInfo.ParameterType.Name, "SwitchParameter", true) == 0) ); } - Parameter param = GetParameterInfo(cmdletInfo, helpItem, paramInfo); - syn.AddParameter(param); } // now take the named parameters. @@ -393,8 +391,6 @@ protected IEnumerable GetSyntaxItem(CommandInfo? cmdletInfo, dynamic string.Compare(paramInfo.ParameterType.Name, "SwitchParameter", true) == 0); syn.SyntaxParameters.Add(sParm); } - Parameter param = GetParameterInfo(cmdletInfo, helpItem, paramInfo); - syn.AddParameter(param); } syntaxItems.Add(syn); diff --git a/src/Transform/TransformMaml.cs b/src/Transform/TransformMaml.cs index 9c3127a9..3c5aeb0e 100644 --- a/src/Transform/TransformMaml.cs +++ b/src/Transform/TransformMaml.cs @@ -19,9 +19,6 @@ namespace Microsoft.PowerShell.PlatyPS { internal class TransformMaml : TransformBase { - // Dictionary of parameter name -> parameterset which it belongs - private Dictionary> _paramSetMap = new(); - public TransformMaml(TransformSettings settings) : base(settings) { } @@ -118,10 +115,9 @@ private Collection ReadMaml(string mamlFile) { cmdHelp.Parameters.RemoveAll(p => string.Compare(p.Name, MAML.Constants.NoCommonParameter, true) == 0); } + cmdHelp.Syntax.ForEach(si => si.HasCmdletBinding = cmdHelp.HasCmdletBinding); cmdHelp.Metadata = MetadataUtils.GetCommandHelpBaseMetadata(cmdHelp); - - _paramSetMap.Clear(); } else { @@ -420,54 +416,27 @@ private Collection ReadSyntaxItems(XmlReader reader) unnamedParameterSetName, isDefaultParameterSet: false); + int position = int.MaxValue; + List positionalSyntaxParameters = []; while (reader.ReadToNextSibling(Constants.MamlCommandParameterTag)) { - var parameter = ReadParameter(reader.ReadSubtree(), parameterSetCount: -1); - syntaxItem.SyntaxParameters.Add(new SyntaxParameter(parameter)); - try + var syntaxParameter = ReadSyntaxParameter(reader.ReadSubtree()); + syntaxItem.SyntaxParameters.Add(syntaxParameter); + if (syntaxParameter.IsPositional) { - // This may possibly throw because the position is duplicated. - // This is because we don't have a way to disambiguate between a positional parameter - // in one parameter set and a non-positional parameter in another parameter set. - // In this case, we will try to add the parameter with a negative position to show we - // could not assign it appropriately. - syntaxItem.AddParameter(parameter); - syntaxItem.SyntaxParameters.Add(new SyntaxParameter(parameter)); - } - catch - { - int minKey = syntaxItem.PositionalParameterKeys.Min(x => x); - if (minKey >= 0) - { - minKey = -1; - } - else - { - minKey--; - } - - parameter.ParameterSets.ForEach(x => x.Position = minKey.ToString()); - try + positionalSyntaxParameters.Add(syntaxParameter); + // set the position value to the minimum value in each parameter + if (int.TryParse(syntaxParameter.Position, NumberStyles.None, CultureInfo.InvariantCulture, out var p)) { - syntaxItem.AddParameter(parameter); - } - catch (Exception exception) - { - throw new InvalidOperationException($"Error adding parameter '{parameter.Name}' to syntax item {commandName}", exception); + position = Math.Min(p, position); } } } - foreach(var paramName in syntaxItem.ParameterNames) + // re-numbering positional parameters from the minimum value + foreach (var p in positionalSyntaxParameters.OrderBy(p => int.Parse(p.Position))) { - if (_paramSetMap.ContainsKey(paramName)) - { - _paramSetMap[paramName].Add(unnamedParameterSetName); - } - else - { - _paramSetMap.Add(paramName, new List() { unnamedParameterSetName }); - } + p.Position = (position++).ToString(); } return syntaxItem; @@ -476,6 +445,76 @@ private Collection ReadSyntaxItems(XmlReader reader) return null; } + private SyntaxParameter ReadSyntaxParameter(XmlReader reader) + { + string name = string.Empty; + string type = string.Empty; + string position = Constants.NamedString; + bool required = false; + + reader.Read(); + + if (reader.HasAttributes) + { + if (reader.MoveToAttribute("required")) + { + bool.TryParse(reader.Value, out required); + } + + if (reader.MoveToAttribute("position")) + { + // Value is like '0' or 'named' + position = reader.Value; + } + + reader.MoveToElement(); + } + + if (reader.ReadToDescendant(Constants.MamlNameTag)) + { + name = reader.ReadElementContentAsString(); + } + + // We read the next element and check the name as it could parameterValue or dev:type + while (reader.Read()) + { + if (string.Equals(reader.Name, Constants.MamlCommandParameterValueTag, StringComparison.OrdinalIgnoreCase)) + { + type = reader.ReadElementContentAsString(); + } + else if (string.IsNullOrEmpty(type) + && string.Equals(reader.Name, Constants.MamlDevTypeTag, StringComparison.OrdinalIgnoreCase)) + { + if (reader.ReadToDescendant(Constants.MamlNameTag)) + { + type = reader.ReadElementContentAsString(); + } + } + } + + if (string.IsNullOrEmpty(type)) + { + throw new InvalidDataException($"Invalid syntaxItem.parameter data: or is none"); + } + + SyntaxParameter syntaxParameter = new SyntaxParameter(name) + { + IsMandatory = required, + ParameterType = type, + IsPositional = int.TryParse(position, NumberStyles.None, CultureInfo.InvariantCulture, out _), + Position = position, + IsSwitchParameter = type is "SwitchParameter" or "System.Management.Automation.SwitchParameter", + }; + + // need to go the end of command:parameter + if (reader.ReadState != ReadState.EndOfFile) + { + reader.ReadEndElement(); + } + + return syntaxParameter; + } + private Parameter ReadParameter(XmlReader reader, int parameterSetCount) { string name = string.Empty; diff --git a/test/Pester/CompareCommandHelp.Tests.ps1 b/test/Pester/CompareCommandHelp.Tests.ps1 index 3f526f1a..20b5b632 100644 --- a/test/Pester/CompareCommandHelp.Tests.ps1 +++ b/test/Pester/CompareCommandHelp.Tests.ps1 @@ -15,23 +15,22 @@ Describe "Compare-CommandHelp can find differences" { } It "Should properly identify the number of differences" { - $result1.where({$_ -match "are not the same|are different"}).Count | Should -Be 11 + $result1.where({$_ -match "are not the same|are different"}).Count | Should -Be 7 } It "Should properly identify the elements which are different" { - $expected = "CommandHelp.Syntax.ParameterSetName", "CommandHelp.Syntax.ParameterNames", "CommandHelp.Syntax.ParameterSetName", - "CommandHelp.Syntax.ParameterNames", "CommandHelp.Syntax.ParameterSetName", "CommandHelp.Syntax.ParameterNames", - "CommandHelp.Syntax.ParameterSetName", "CommandHelp.Syntax.ParameterNames", "CommandHelp.Examples.Title", - "CommandHelp.Examples.Remarks", "CommandHelp.Diagnostics" + $expected = "CommandHelp.Syntax.ParameterSetName", "CommandHelp.Syntax.ParameterSetName", + "CommandHelp.Syntax.ParameterSetName", "CommandHelp.Syntax.ParameterSetName", + "CommandHelp.Examples.Title", "CommandHelp.Examples.Remarks", + "CommandHelp.Diagnostics" $observed = $result1.split("`n").Where({$_ -match "are not the same|are different"}).foreach({$_.Substring(2).trim().split()[0]}) $observed | Should -Be $expected } It "Should be possible to exclude an element from comparison" { - $expected = "CommandHelp.Syntax.ParameterSetName", "CommandHelp.Syntax.ParameterNames", "CommandHelp.Syntax.ParameterSetName", - "CommandHelp.Syntax.ParameterNames", "CommandHelp.Syntax.ParameterSetName", "CommandHelp.Syntax.ParameterNames", - "CommandHelp.Syntax.ParameterSetName", "CommandHelp.Syntax.ParameterNames", "CommandHelp.Examples.Title", - "CommandHelp.Examples.Remarks" + $expected = "CommandHelp.Syntax.ParameterSetName", "CommandHelp.Syntax.ParameterSetName", + "CommandHelp.Syntax.ParameterSetName", "CommandHelp.Syntax.ParameterSetName", + "CommandHelp.Examples.Title", "CommandHelp.Examples.Remarks" $observed = $result2.split("`n").Where({$_ -match "are not the same|are different"}).foreach({$_.Substring(2).trim().split()[0]}) $observed | Should -Be $expected @@ -39,8 +38,7 @@ Describe "Compare-CommandHelp can find differences" { It "Default excluded properties should be Diagnostics and ParameterNames" { $expected = "M excluding comparison of CommandHelp.AliasHeaderFound", - "M excluding comparison of CommandHelp.Diagnostics", - "M excluding comparison of CommandHelp.Syntax.ParameterNames" + "M excluding comparison of CommandHelp.Diagnostics" $observed = $result3.split("`n").Where({$_ -match "excluding comparison"})|Sort-Object -Unique $observed | Should -Be $expected } diff --git a/test/Pester/ExportMamlCommandHelp.Tests.ps1 b/test/Pester/ExportMamlCommandHelp.Tests.ps1 index 619155bc..f7d8c268 100644 --- a/test/Pester/ExportMamlCommandHelp.Tests.ps1 +++ b/test/Pester/ExportMamlCommandHelp.Tests.ps1 @@ -143,5 +143,65 @@ Describe "Export-MamlCommandHelp tests" { $maml = Get-Content -Path $mamlFile -Raw $maml | Should -BeLike '*https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/get-date?view=powershell-7.4&WT.mc_id=ps-gethelp*' } + + It "Should have the proper aliases for Get-Date" { + $xml2.SelectNodes('//command:command', $ns2).Where({$_.details.name -eq "Get-Date"}).Parameters.parameter. + Where({$_.Name -in @('Date', 'UnixTimeSeconds')}).aliases | Should -Be 'LastWriteTime', 'UnixTime' + } + + It "Should have the proper parameterValueGroup for 'DisplayHint' parameter of Get-Date" { + $parameter = $xml2.SelectNodes('//command:command', $ns2).Where({$_.details.name -eq "Get-Date"}). + parameters.parameter.Where({$_.Name -eq 'DisplayHint'}) + $parameter.SelectNodes('./command:parameterValueGroup/command:parameterValue', $ns2).'#text' | + Should -BeExactly 'Date', 'Time', 'DateTime' + } + + It "Should have the proper values for '' syntax parameter of Get-Date" -testcases @( + @{ name = "Date"; position = "0"; aliases = "LastWriteTime"; parameterValue = "DateTime"; type = "System.DateTime"; }, + @{ name = "Year"; position = "named"; aliases = "none"; parameterValue = "Int32"; type = "System.Int32"; }, + @{ name = "AsUTC"; position = "named"; aliases = "none"; parameterValue = $null; type = "System.Management.Automation.SwitchParameter" } + ) { + param($name, $position, $aliases, $parameterValue, $type) + + $command = $xml2.SelectNodes('//command:command', $ns2).Where({$_.details.name -eq "Get-Date"}) + $syntaxParam = $command.syntax.syntaxItem[0].parameter.Where({$_.name -eq $name}); + $syntaxParam.Count | Should -Be 1; + $syntaxParam.position | Should -BeExactly $position + $syntaxParam.aliases | Should -BeExactly $aliases + if ($null -eq $parameterValue) + { + $syntaxParam.parameterValue | Should -BeNullOrEmpty + } + else + { + $syntaxParam.parameterValue."#text" | Should -BeExactly $parameterValue + $syntaxParam.parameterValue.required | Should -BeExactly 'true' + } + $syntaxParam.type.name | Should -BeExactly $type + } + + It "Should have the proper values for '' parameter of Get-Date" -testcases @( + @{ name = "Date"; position = "0"; aliases = "LastWriteTime"; parameterValue = "System.DateTime"; type = "System.DateTime"; }, + @{ name = "Year"; position = "Named"; aliases = "none"; parameterValue = "System.Int32"; type = "System.Int32"; }, + @{ name = "AsUTC"; position = "Named"; aliases = "none"; parameterValue = $null; type = "System.Management.Automation.SwitchParameter" } + ) { + param($name, $position, $aliases, $parameterValue, $type) + + $command = $xml2.SelectNodes('//command:command', $ns2).Where({$_.details.name -eq "Get-Date"}) + $param = $command.parameters.parameter.Where({$_.name -eq $name}); + $param.Count | Should -Be 1; + $param.position | Should -BeExactly $position + $param.aliases | Should -BeExactly $aliases + if ($null -eq $parameterValue) + { + $param.parameterValue | Should -BeNullOrEmpty + } + else + { + $param.parameterValue."#text" | Should -BeExactly $parameterValue + $param.parameterValue.required | Should -BeExactly 'true' + } + $param.type.name | Should -BeExactly $type + } } } diff --git a/test/Pester/ImportMamlHelp.Tests.ps1 b/test/Pester/ImportMamlHelp.Tests.ps1 index d50d280c..9365b7bf 100644 --- a/test/Pester/ImportMamlHelp.Tests.ps1 +++ b/test/Pester/ImportMamlHelp.Tests.ps1 @@ -46,5 +46,31 @@ Describe "Import-YamlHelp tests" { $cmdlet.Metadata[$key] | Should -Be $Value } } + + Context "Syntax parameters checks" { + It "Add-Member cmdlet has correct number of syntax parameters" { + $cmdlet.Syntax[0].SyntaxParameters.Count | Should -be 8 + } + + It "'' of syntax parameter for Add-Member cmdlet has correct property values" -testcases @( + @{ Name = 'MemberType'; Type = 'System.Management.Automation.PSMemberTypes'; Position = '0'; IsMandatory = $true; IsPositional = $true; IsSwitchParameter = $false }, + @{ Name = 'Name'; Type = 'System.String'; Position = '1'; IsMandatory = $true; IsPositional = $true; IsSwitchParameter = $false }, + @{ Name = 'Value'; Type = 'System.Object'; Position = '2'; IsMandatory = $false; IsPositional = $true; IsSwitchParameter = $false }, + @{ Name = 'SecondValue'; Type = 'System.Object'; Position = '3'; IsMandatory = $false; IsPositional = $true; IsSwitchParameter = $false }, + @{ Name = 'Force'; Type = 'System.Management.Automation.SwitchParameter'; Position = 'named'; IsMandatory = $false; IsPositional = $false; IsSwitchParameter = $true }, + @{ Name = 'InputObject'; Type = 'System.Management.Automation.PSObject'; Position = 'named'; IsMandatory = $true; IsPositional = $false; IsSwitchParameter = $false }, + @{ Name = 'PassThru'; Type = 'System.Management.Automation.SwitchParameter'; Position = 'named'; IsMandatory = $false; IsPositional = $false; IsSwitchParameter = $true }, + @{ Name = 'TypeName'; Type = 'System.String'; Position = 'named'; IsMandatory = $false; IsPositional = $false; IsSwitchParameter = $false } + ) { + param ([string]$Name, [string]$Type, [string]$Position, [bool]$IsMandatory, [bool]$IsPositional, [bool]$IsSwitchParameter) + $syntaxParam = $cmdlet.Syntax[0].SyntaxParameters.Where({$_.ParameterName -eq $Name}) + $syntaxParam.ParameterName | Should -be $Name + $syntaxParam.ParameterType | Should -be $Type + $syntaxParam.Position | should -be $Position + $syntaxParam.IsMandatory | should -be $IsMandatory + $syntaxParam.IsPositional | should -be $IsPositional + $syntaxParam.IsSwitchParameter | should -be $IsSwitchParameter + } + } } -} \ No newline at end of file +}