Skip to content

Commit

Permalink
🚀 [Feature]: Add ValidationErrorMessage and `ValidatePatternOptions…
Browse files Browse the repository at this point in the history
…` parameters (#8)

## Description

- Added `ValidationErrorMessage` parameter that is supported for
`ValidatePattern`, `ValidateScript` and `ValidateSet` to override the
default error message. This is not supported on Desktop version.
- Added `ValidatePatternOptions` parameter that is supported for
`ValidatePattern` to set options for the regular expression operation.
- Added unit and integration tests.

## Type of change

<!-- Use the check-boxes [x] on the options that are relevant. -->

- [ ] đź“– [Docs]
- [ ] 🪲 [Fix]
- [ ] đź©ą [Patch]
- [ ] ⚠️ [Security fix]
- [x] 🚀 [Feature]
- [ ] 🌟 [Breaking change]

## Checklist

<!-- Use the check-boxes [x] on the options that are relevant. -->

- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
  • Loading branch information
MariusStorhaug committed Apr 1, 2024
1 parent 257e91b commit e6a624f
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 86 deletions.
42 changes: 0 additions & 42 deletions examples/DynamicParam.ps1

This file was deleted.

43 changes: 0 additions & 43 deletions examples/DynamicParam2.ps1

This file was deleted.

35 changes: 35 additions & 0 deletions src/public/New-DynamicParam.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@
[Parameter()]
[regex] $ValidatePattern,

# Specifies the validate regular expression pattern options of the parameter.
# For more info see [RegexOptions](https://learn.microsoft.com/dotnet/api/system.text.regularexpressions.regexoptions).
[Parameter()]
[System.Text.RegularExpressions.RegexOptions[]] $ValidatePatternOptions,

# Specifies the validate number of items for the parameter.
[Parameter()]
[ValidateCount(2, 2)]
Expand All @@ -118,6 +123,16 @@
[Parameter()]
[switch] $ValidateNotNullOrEmpty,

# The custom error message pattern that is displayed to the user if validation fails.
# This parameter is not supported on Windows PowerShell Desktop Edition, if specified it will be ignored.
#
# Examples of how to use this parameter:
# - `ValidatePattern` -> "The text '{0}' did not pass validation of the regular expression '{1}'". {0} is the value, {1} is the pattern.
# - `ValidateSet` -> "The item '{0}' is not part of the set '{1}'. {0} is the value, {1} is the set.
# - `ValidateScript` -> "The item '{0}' did not pass validation of script '{1}'". {0} is the value, {1} is the script.
[Parameter()]
[string] $ValidationErrorMessage,

# Specifies if the parameter accepts wildcards.
[Parameter()]
[switch] $SupportsWildcards,
Expand All @@ -139,6 +154,14 @@
[System.Management.Automation.RuntimeDefinedParameterDictionary] $DynamicParamDictionary
)

$isDesktop = $PSVersionTable.PSEdition -eq 'Desktop'

if ($isDesktop) {
if ($PSBoundParameters.ContainsKey('ValidationErrorMessage')) {
Write-Warning "Unsupported parameter: 'ValidationErrorMessage' is not supported in Windows PowerShell Desktop Edition. Skipping it."
}
}

$attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]

# foreach ParameterSet in ParameterSets , Key = name, Value = Hashtable
Expand Down Expand Up @@ -168,6 +191,9 @@

if ($PSBoundParameters.ContainsKey('ValidateSet')) {
$validateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidateSet)
if ($PSBoundParameters.ContainsKey('ValidationErrorMessage') -and -not $isDesktop) {
$validateSetAttribute.ErrorMessage = $ValidationErrorMessage
}
$attributeCollection.Add($validateSetAttribute)
}
if ($PSBoundParameters.ContainsKey('ValidateNotNullOrEmpty')) {
Expand All @@ -184,10 +210,19 @@
}
if ($PSBoundParameters.ContainsKey('ValidateScript')) {
$validateScriptAttribute = New-Object System.Management.Automation.ValidateScriptAttribute($ValidateScript)
if ($PSBoundParameters.ContainsKey('ValidationErrorMessage') -and -not $isDesktop) {
$validateScriptAttribute.ErrorMessage = $ValidationErrorMessage
}
$attributeCollection.Add($validateScriptAttribute)
}
if ($PSBoundParameters.ContainsKey('ValidatePattern')) {
$validatePatternAttribute = New-Object System.Management.Automation.ValidatePatternAttribute($ValidatePattern)
if ($PSBoundParameters.ContainsKey('ValidationErrorMessage') -and -not $isDesktop) {
$validatePatternAttribute.ErrorMessage = $ValidationErrorMessage
}
if ($PSBoundParameters.ContainsKey('ValidatePatternOptions')) {
$validatePatternAttribute.Options = $ValidatePatternOptions
}
$attributeCollection.Add($validatePatternAttribute)
}
if ($PSBoundParameters.ContainsKey('ValidateRange')) {
Expand Down
2 changes: 1 addition & 1 deletion src/public/New-DynamicParamDictionary.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
[CmdletBinding()]
param()

return [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
[System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
}
127 changes: 127 additions & 0 deletions tests/DynamicParams.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,131 @@ Describe 'DynamicParams' {
{ Import-Module -Name 'DynamicParams' -Verbose -RequiredVersion 999.0.0 -Force } | Should -Not -Throw
}
}

Context 'Function: New-DynamicParamDictionary' {
It 'New-DynamicParamDictionary should not throw an exception' {
{ New-DynamicParamDictionary } | Should -Not -Throw
}

It 'New-DynamicParamDictionary should return a RuntimeDefinedParameterDictionary' {
$dictionary = New-DynamicParamDictionary
$dictionary | Should -BeOfType 'System.Management.Automation.RuntimeDefinedParameterDictionary'
}
}

Context 'Function: New-DynamicParam' {
It 'New-DynamicParam should not throw an exception' {
$dictionary = New-DynamicParamDictionary
$dynParam = @{
Name = 'Param1'
Type = [string]
ValidateSet = 'A', 'B', 'C'
DynamicParamDictionary = $dictionary
}
{ New-DynamicParam @dynParam } | Should -Not -Throw
}

It 'New-DynamicParam should add a RuntimeDefinedParameter to the dictionary' {
$dictionary = New-DynamicParamDictionary
$dynParam = @{
Name = 'Param1'
Type = [string]
ValidateSet = 'A', 'B', 'C'
DynamicParamDictionary = $dictionary
}
New-DynamicParam @dynParam
$dictionary.Keys | Should -Contain 'Param1'
}
}

Context 'Integration' {
BeforeAll {
filter Test-DynParam {
[CmdletBinding()]
param (
[Parameter()]
[ValidateSet('A', 'B', 'C')]
[string]$Param1
)

DynamicParam {
$DynamicParamDictionary = New-DynamicParamDictionary

$dynVariable = @{
Name = 'Variable'
Type = [string]
ValidateSet = Get-Variable | Select-Object -ExpandProperty Name
DynamicParamDictionary = $DynamicParamDictionary
}
New-DynamicParam @dynVariable

$dynEnvironmentVariable = @{
Name = 'EnvironmentVariable'
Type = [string]
ValidateSet = Get-ChildItem -Path env: | Select-Object -ExpandProperty Name
DynamicParamDictionary = $DynamicParamDictionary
}
New-DynamicParam @dynEnvironmentVariable

return $DynamicParamDictionary
}

process {
$Variable = $PSBoundParameters['Variable']
$EnvironmentVariable = $PSBoundParameters['EnvironmentVariable']

Write-Verbose "Variable: $Variable"
Write-Verbose "EnvironmentVariable: $EnvironmentVariable"
}
}

filter Test-DynParam2 {
[CmdletBinding()]
param (
[Parameter()]
[ValidateSet('A', 'B', 'C')]
[string]$Param1
)

DynamicParam {
$DynamicParamDictionary = New-DynamicParamDictionary

$dynVariable = @{
Name = 'Variable'
Type = [string]
ValidateSet = Get-Variable | Select-Object -ExpandProperty Name
DynamicParamDictionary = $DynamicParamDictionary
}
New-DynamicParam @dynVariable

$dynEnvironmentVariable = @{
Name = 'EnvironmentVariable'
Type = [string]
ValidateSet = Get-ChildItem -Path env: | Select-Object -ExpandProperty Name
DynamicParamDictionary = $DynamicParamDictionary
}
New-DynamicParam @dynEnvironmentVariable

return $DynamicParamDictionary
}

process {
$PSBoundParameters.Keys | ForEach-Object {
Set-Variable -Name $_ -Value $PSBoundParameters[$_]
}

Write-Verbose "Variable: $Variable"
Write-Verbose "EnvironmentVariable: $EnvironmentVariable"
}
}
}

It 'Test-DynParam should not throw an exception' {
{ Test-DynParam -Variable HOME -EnvironmentVariable RUNNER_OS -Verbose } | Should -Not -Throw
}

It 'Test-DynParam2 should not throw an exception' {
{ Test-DynParam2 -Variable HOME -EnvironmentVariable RUNNER_OS -Verbose } | Should -Not -Throw
}
}
}

0 comments on commit e6a624f

Please sign in to comment.