Skip to content

test(classes): add contract tests for class layer#62

Merged
HeyItsGilbert merged 1 commit into
mainfrom
worktree-linear-munching-mango
May 12, 2026
Merged

test(classes): add contract tests for class layer#62
HeyItsGilbert merged 1 commit into
mainfrom
worktree-linear-munching-mango

Conversation

@HeyItsGilbert
Copy link
Copy Markdown
Owner

Fixes #24.

Adds tests/Classes.tests.ps1 with contract tests for ConditionGroup, ConditionGroupTransformAttribute, PropertyDefinition.Validate, PropertySet, and FeatureFlag.

Also fixes four bugs exposed by the new tests:

  • PropertyValidation: Use [Nullable[int]] for integer constraint fields so unset constraints (MinLength, MaxLength, etc.) are not incorrectly applied during validation.
  • PropertyValidation.ToHashtable: Omit null/unset fields so saved JSON passes schema validation on a Save -> FromFile round-trip.
  • ConditionGroup constructor: Treat keys present with null values as absent (handles ConvertTo-Json round-trips that serialize all class fields). Use Property presence (not Operator) as the canonical signal for a flat/leaf condition — Operator's enum default is always serialized as a non-null string, making it unreliable as a discriminator.
  • FeatureFlag constructor: Handle Version deserialized as a dictionary from a ConvertTo-Json round-trip rather than a version string.

Test coverage added

  • ConditionGroup constructor: mutual exclusion of AllOf/AnyOf/Not; Property without Operator/Value; group+flat mix
  • ConditionGroup.IsValid: flat leaf returns true; cleared Value returns false
  • ConditionGroup.ToString: flat, AllOf, AnyOf, Not, nested
  • ConditionGroupTransformAttribute: hashtable, passthrough, file path, unsupported type (all via Test-Condition)
  • PropertyDefinition.Validate: all constraint violations + pass cases
  • PropertySet: AddProperty keying/chaining, GetProperty, ContainsKey, FromFile name, Save/FromFile round-trip
  • FeatureFlag: FromJson, FromFile, Save round-trip

…atureFlag, and transform attributes

Also fixes three bugs uncovered by the tests:
- PropertyValidation: use Nullable[int] so unset constraints are not incorrectly applied
- PropertyValidation.ToHashtable: omit null/unset fields to pass schema validation on round-trip
- ConditionGroup constructor: treat null-valued keys as absent; use Property presence (not Operator) to detect flat vs group conditions so JSON round-trips do not falsely trigger mutual-exclusion or mixed-field errors
- FeatureFlag constructor: handle Version deserialized as a dictionary (from ConvertTo-Json round-trip) instead of a version string

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Test Results

  3 files  279 suites   5s ⏱️
309 tests 304 ✅  5 💤 0 ❌
927 runs  912 ✅ 15 💤 0 ❌

Results for commit a26b910.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Pester contract test suite for Gatekeeper’s class layer (ConditionGroup/PropertySet/FeatureFlag and related transforms) and updates core class constructors/serialization helpers to support JSON round-trips and stricter validation semantics.

Changes:

  • Added tests/Classes.tests.ps1 contract coverage for ConditionGroup, transform attributes, PropertyDefinition.Validate, PropertySet, and FeatureFlag.
  • Updated PropertyValidation to use nullable constraint fields and omit unset fields during serialization to support schema-valid round-trips.
  • Updated ConditionGroup and FeatureFlag constructors to better handle ConvertTo-Json round-trips (null/default field presence, Version shape).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
tests/Classes.tests.ps1 Adds class-layer contract tests covering constructors, validation, stringification, transforms, and save/load round-trips.
Gatekeeper/Classes/Property.ps1 Fixes validation constraint defaults via nullable ints and omits unset validation fields in ToHashtable().
Gatekeeper/Classes/FeatureFlag.ps1 Adjusts ConditionGroup parsing rules for null/default fields and adds FeatureFlag Version dictionary handling.

Comment on lines +32 to 55
# Property presence (non-null) is the canonical signal for a flat/leaf condition.
# Operator is excluded from this check because its enum default ("Equals") is always
# serialized as a non-null string in JSON round-trips, making it unreliable as a signal.
$hasGroup = $groupKeys.Count -gt 0
$hasProperty = $data.ContainsKey('Property') -and $null -ne $data['Property']
if ($hasGroup -and $hasProperty) {
throw "ConditionGroup with AllOf, AnyOf, or Not cannot also have Property, Operator, and Value defined."
}
if ($data.ContainsKey('Property') -and
(-not $data.ContainsKey('Operator') -or -not $data.ContainsKey('Value'))) {
throw "ConditionGroup with Property must also have Operator and Value defined."
if ($hasProperty) {
$hasOperator = $data.ContainsKey('Operator') -and $null -ne $data['Operator']
$hasValue = $data.ContainsKey('Value') -and $null -ne $data['Value']
if (-not $hasOperator -or -not $hasValue) {
throw "ConditionGroup with Property must also have Operator and Value defined."
}
}
if ($data.ContainsKey('Property')) {
if ($hasProperty) {
$this.Property = $data.Property
}
if ($data.ContainsKey('Operator')) {
if ($data.ContainsKey('Operator') -and $null -ne $data['Operator']) {
$this.Operator = $data.Operator
}
if ($data.ContainsKey('Value')) {
if ($data.ContainsKey('Value') -and $null -ne $data['Value']) {
$this.Value = $data.Value
}
Comment on lines +169 to +180
if ($null -ne $data.Version) {
if ($data.Version -is [System.Collections.IDictionary]) {
$b = [int]$data.Version.Build
$this.Version = if ($b -ge 0) {
[version]"$($data.Version.Major).$($data.Version.Minor).$b"
} else {
[version]"$($data.Version.Major).$($data.Version.Minor)"
}
} else {
$this.Version = [version]$data.Version
}
}
@HeyItsGilbert HeyItsGilbert merged commit 41e5745 into main May 12, 2026
10 checks passed
@HeyItsGilbert HeyItsGilbert deleted the worktree-linear-munching-mango branch May 12, 2026 01:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: add class-level contract tests for ConditionGroup, PropertySet, FeatureFlag, and transform attributes

2 participants