From 200cf6a9ca6522d9573c66d1d57c8d543432a33c Mon Sep 17 00:00:00 2001 From: Gilbert Sanchez Date: Wed, 13 May 2026 17:14:09 -0700 Subject: [PATCH] fix(validation): remove duplicate Test-TypedValue helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test-TypedValue duplicated integer/string min/max/length/pattern logic already implemented in PropertyDefinition.Validate, with a divergent contract (throws vs Write-Warning + bool return). It was unreferenced in the module — only its own tests exercised it. Test-Condition already routes through PropertyDefinition.Validate, so removing the helper collapses validation to a single canonical contract. Co-Authored-By: Claude Opus 4.7 --- CLAUDE.md | 2 +- Gatekeeper/Private/Test-TypedValue.ps1 | 46 --------------- tests/Test-TypedValue.tests.ps1 | 81 -------------------------- 3 files changed, 1 insertion(+), 128 deletions(-) delete mode 100644 Gatekeeper/Private/Test-TypedValue.ps1 delete mode 100644 tests/Test-TypedValue.tests.ps1 diff --git a/CLAUDE.md b/CLAUDE.md index fcc659c..e5f3d76 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -56,7 +56,7 @@ The module follows a standard PowerShell module layout: - **Classes/**: PowerShell class definitions (Property.ps1, FeatureFlag.ps1) - **Enums/**: Enumeration definitions (Effect.ps1) - **Public/**: Exported functions (Test-FeatureFlag, New-FeatureFlag, etc.) - - **Private/**: Internal helper functions (Convert-ToTypeValue, Test-TypedValue) + - **Private/**: Internal helper functions (Convert-ToTypedValue) - **Schemas/**: JSON schemas for validation (FeatureFlag.json, Properties.json) - **Configuration.psd1**: Default module configuration - **Gatekeeper.psm1**: Module loader that dot-sources all functions and registers type accelerators diff --git a/Gatekeeper/Private/Test-TypedValue.ps1 b/Gatekeeper/Private/Test-TypedValue.ps1 deleted file mode 100644 index 3ea23fd..0000000 --- a/Gatekeeper/Private/Test-TypedValue.ps1 +++ /dev/null @@ -1,46 +0,0 @@ -function Test-TypedValue { - [CmdletBinding()] - param ( - [Parameter(Mandatory)] - $Value, - [Parameter(Mandatory, ParameterSetName = "WithPropertyDefinition")] - [PropertyDefinition] - $PropertyDefinition, - [Parameter(Mandatory, ParameterSetName = "WithOutPropertyDefinition")] - [string] - $Type, - [Parameter(Mandatory, ParameterSetName = "WithOutPropertyDefinition")] - $Name, - [Parameter(Mandatory, ParameterSetName = "WithOutPropertyDefinition")] - $Validation - ) - - if ($PSCmdlet.ParameterSetName -eq "WithPropertyDefinition" ) { - $PropertyDefinition.Validate($Value) | Out-Null - return - } - - if (-not $Validation) { return } - - switch ($Type.ToLower()) { - "integer" { - if ($null -ne $Validation.Minimum -and $Value -lt $Validation.Minimum) { - throw "Value for '$Name' ($Value) is less than minimum allowed ($($Validation.Minimum))" - } - if ($null -ne $Validation.Maximum -and $Value -gt $Validation.Maximum) { - throw "Value for '$Name' ($Value) is greater than maximum allowed ($($Validation.Maximum))" - } - } - "string" { - if ($null -ne $Validation.MinLength -and $Value.Length -lt $Validation.MinLength) { - throw "Value for '$Name' is shorter than MinLength ($($Validation.MinLength))" - } - if ($null -ne $Validation.MaxLength -and $Value.Length -gt $Validation.MaxLength) { - throw "Value for '$Name' is longer than MaxLength ($($Validation.MaxLength))" - } - if ($Validation.Pattern -and ($Value -notmatch $Validation.Pattern)) { - throw "Value for '$Name' does not match pattern '$($Validation.Pattern)'" - } - } - } -} diff --git a/tests/Test-TypedValue.tests.ps1 b/tests/Test-TypedValue.tests.ps1 deleted file mode 100644 index bd33756..0000000 --- a/tests/Test-TypedValue.tests.ps1 +++ /dev/null @@ -1,81 +0,0 @@ -BeforeDiscovery { - $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest - $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' - $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName - $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion - $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" - - # Remove all versions of the module from the session. Pester can't handle multiple versions. - Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore - Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop -} -Describe 'Test-TypedValue' { - Context 'WithPropertyDefinition parameter set' { - It 'delegates to PropertyDefinition.Validate for a valid value' { - InModuleScope $env:BHProjectName { - $prop = [PropertyDefinition]::new('Score', @{ Type = 'integer'; Validation = @{ Minimum = 1; Maximum = 10 } }) - { Test-TypedValue -PropertyDefinition $prop -Value 5 } | Should -Not -Throw - } - } - It 'delegates to PropertyDefinition.Validate and does not throw for an invalid value' { - InModuleScope $env:BHProjectName { - $prop = [PropertyDefinition]::new('Score', @{ Type = 'integer'; Validation = @{ Minimum = 1; Maximum = 10 } }) - { Test-TypedValue -PropertyDefinition $prop -Value 0 } | Should -Not -Throw - } - } - } - Context 'WithOutPropertyDefinition parameter set - integer constraints' { - It 'throws when value is below Minimum' { - InModuleScope $env:BHProjectName { - $validation = @{ Minimum = 1; Maximum = 10 } - { Test-TypedValue -Type 'integer' -Name 'Score' -Validation $validation -Value 0 } | Should -Throw - } - } - It 'throws when value is above Maximum' { - InModuleScope $env:BHProjectName { - $validation = @{ Minimum = 1; Maximum = 10 } - { Test-TypedValue -Type 'integer' -Name 'Score' -Validation $validation -Value 11 } | Should -Throw - } - } - It 'passes when value is within range' { - InModuleScope $env:BHProjectName { - $validation = @{ Minimum = 1; Maximum = 10 } - { Test-TypedValue -Type 'integer' -Name 'Score' -Validation $validation -Value 5 } | Should -Not -Throw - } - } - } - Context 'WithOutPropertyDefinition parameter set - string constraints' { - It 'throws when value is shorter than MinLength' { - InModuleScope $env:BHProjectName { - $validation = @{ MinLength = 5 } - { Test-TypedValue -Type 'string' -Name 'Tag' -Validation $validation -Value 'abc' } | Should -Throw - } - } - It 'throws when value is longer than MaxLength' { - InModuleScope $env:BHProjectName { - $validation = @{ MaxLength = 5 } - { Test-TypedValue -Type 'string' -Name 'Tag' -Validation $validation -Value 'toolongstring' } | Should -Throw - } - } - It 'throws when value does not match Pattern' { - InModuleScope $env:BHProjectName { - $validation = @{ Pattern = '^[a-z]+$' } - { Test-TypedValue -Type 'string' -Name 'Tag' -Validation $validation -Value 'ABC123' } | Should -Throw - } - } - It 'passes when value matches Pattern' { - InModuleScope $env:BHProjectName { - $validation = @{ Pattern = '^[a-z]+$' } - { Test-TypedValue -Type 'string' -Name 'Tag' -Validation $validation -Value 'abc' } | Should -Not -Throw - } - } - } - Context 'WithPropertyDefinition parameter set - no validation configured' { - It 'returns cleanly when PropertyDefinition has no Validation set' { - InModuleScope $env:BHProjectName { - $prop = [PropertyDefinition]::new('Score', @{ Type = 'integer' }) - { Test-TypedValue -PropertyDefinition $prop -Value 999 } | Should -Not -Throw - } - } - } -}