diff --git a/src/System.Management.Automation/engine/Attributes.cs b/src/System.Management.Automation/engine/Attributes.cs index f82e37e11a5..d501f395903 100644 --- a/src/System.Management.Automation/engine/Attributes.cs +++ b/src/System.Management.Automation/engine/Attributes.cs @@ -1014,7 +1014,12 @@ public sealed class ValidateRangeAttribute : ValidateEnumeratedArgumentsAttribut /// private Type _promotedType; - ValidateRangeKind? _rangeKind; + /// + /// Gets the name of the predefined range. + /// + internal ValidateRangeKind? RangeKind { get => _rangeKind; } + + private ValidateRangeKind? _rangeKind; /// /// Validates that each parameter argument falls in the range diff --git a/src/System.Management.Automation/engine/TypeMetadata.cs b/src/System.Management.Automation/engine/TypeMetadata.cs index 81353802046..f54b326e7eb 100644 --- a/src/System.Management.Automation/engine/TypeMetadata.cs +++ b/src/System.Management.Automation/engine/TypeMetadata.cs @@ -758,6 +758,7 @@ internal bool IsMatchingType(PSTypeName psTypeName) private const string ParameterSetNameFormat = "ParameterSetName='{0}'"; private const string AliasesFormat = @"{0}[Alias({1})]"; private const string ValidateLengthFormat = @"{0}[ValidateLength({1}, {2})]"; + private const string ValidateRangeRangeKindFormat = @"{0}[ValidateRange([System.Management.Automation.ValidateRangeKind]::{1})]"; private const string ValidateRangeFloatFormat = @"{0}[ValidateRange({1:R}, {2:R})]"; private const string ValidateRangeFormat = @"{0}[ValidateRange({1}, {2})]"; private const string ValidatePatternFormat = "{0}[ValidatePattern('{1}')]"; @@ -899,31 +900,48 @@ private string GetProxyAttributeData(Attribute attrib, string prefix) ValidateLengthAttribute validLengthAttrib = attrib as ValidateLengthAttribute; if (validLengthAttrib != null) { - result = string.Format(CultureInfo.InvariantCulture, + result = string.Format( + CultureInfo.InvariantCulture, ValidateLengthFormat, prefix, - validLengthAttrib.MinLength, validLengthAttrib.MaxLength); + validLengthAttrib.MinLength, + validLengthAttrib.MaxLength); return result; } ValidateRangeAttribute validRangeAttrib = attrib as ValidateRangeAttribute; if (validRangeAttrib != null) { - Type rangeType = validRangeAttrib.MinRange.GetType(); - string format; - - if (rangeType == typeof(float) || rangeType == typeof(double)) + if (validRangeAttrib.RangeKind.HasValue) { - format = ValidateRangeFloatFormat; + result = string.Format( + CultureInfo.InvariantCulture, + ValidateRangeRangeKindFormat, + prefix, + validRangeAttrib.RangeKind.ToString()); + return result; } else { - format = ValidateRangeFormat; - } + Type rangeType = validRangeAttrib.MinRange.GetType(); + string format; - result = string.Format(CultureInfo.InvariantCulture, - format, prefix, - validRangeAttrib.MinRange, validRangeAttrib.MaxRange); - return result; + if (rangeType == typeof(float) || rangeType == typeof(double)) + { + format = ValidateRangeFloatFormat; + } + else + { + format = ValidateRangeFormat; + } + + result = string.Format( + CultureInfo.InvariantCulture, + format, + prefix, + validRangeAttrib.MinRange, + validRangeAttrib.MaxRange); + return result; + } } AllowNullAttribute allowNullAttrib = attrib as AllowNullAttribute; diff --git a/test/powershell/engine/Basic/ProxyCommand.tests.ps1 b/test/powershell/engine/Basic/ProxyCommand.tests.ps1 new file mode 100644 index 00000000000..947c4634249 --- /dev/null +++ b/test/powershell/engine/Basic/ProxyCommand.tests.ps1 @@ -0,0 +1,60 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +Describe 'ProxyCommand Tests' -Tag 'CI' { + BeforeAll { + $testCases = @( + @{ Name = 'ValidateLengthAttribute'; ParamBlock = '[ValidateLength(1, 10)][int]${Parameter}' } + @{ Name = 'ValidateRangeAttribute with Minimum and Maximum'; ParamBlock = '[ValidateRange(1, 10)][int]${Parameter}' } + @{ Name = 'ValidateRangeAttribute with RangeKind'; ParamBlock = '[ValidateRange([System.Management.Automation.ValidateRangeKind]::Positive)][int]${Parameter}' } + @{ Name = 'AllowNullAttribute'; ParamBlock = '[AllowNull()][int]${Parameter}' } + @{ Name = 'AllowEmptyStringAttribute'; ParamBlock = '[AllowEmptyString()][int]${Parameter}' } + @{ Name = 'AllowEmptyCollectionAttribute'; ParamBlock = '[AllowEmptyCollection()][int]${Parameter}' } + @{ Name = 'ValidatePatternAttribute'; ParamBlock = '[ValidatePattern(''.*'')][int]${Parameter}' } + @{ Name = 'ValidateCountAttribute'; ParamBlock = '[ValidateCount(1, 10)][int]${Parameter}' } + @{ Name = 'ValidateNotNullAttribute'; ParamBlock = '[ValidateNotNull()][int]${Parameter}' } + @{ Name = 'ValidateNotNullOrEmptyAttribute'; ParamBlock = '[ValidateNotNullOrEmpty()][int]${Parameter}' } + @{ Name = 'ValidateSetAttribute with explicit set'; ParamBlock = '[ValidateSet(''1'',''10'')][int]${Parameter}' } + @{ Name = 'PSTypeNameAttribute'; ParamBlock = '[PSTypeName(''TypeName'')][int]${Parameter}' } + ) + } + + Context 'GetParamBlock method' { + AfterAll { + Remove-Item function:testProxyCommandFunction -ErrorAction SilentlyContinue + } + + It 'Generates a param block when is used' -TestCases $testCases { + param ( + $Name, + $ParamBlock + ) + + $functionDefinition = 'param ( {0} )' -f $ParamBlock + Set-Item -Path function:testProxyCommandFunction -Value $functionDefinition + + $generatedParamBlock = [System.Management.Automation.ProxyCommand]::GetParamBlock( + (Get-Command testProxyCommandFunction) + ) + $generatedParamBlock = $generatedParamBlock -split '\r?\n' -replace '^ *' -join '' + + $generatedParamBlock | Should -Be $ParamBlock + } + + It 'Generates a param block when ValidateScriptAttribute is used' { + param ( + $Name, + $ParamBlock + ) + + $functionDefinition = 'param ( [ValidateScript({ $true })][int]${Parameter} )' + Set-Item -Path function:testProxyCommandFunction -Value $functionDefinition + $generatedParamBlock = [System.Management.Automation.ProxyCommand]::GetParamBlock( + (Get-Command testProxyCommandFunction) + ) + $generatedParamBlock = $generatedParamBlock -split '\r?\n' -replace '^ *' -join '' + + $generatedParamBlock | Should -Be '[ValidateScript({ $true })][int]${Parameter}' + } + } +}