From 0d519d1457ca1245b5ab8e4258cc693460ed190e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Aug 2026 03:16:50 +0200 Subject: [PATCH 1/2] Raise code coverage target to 80% The actual test coverage is 85%, so the 25% gate was far below production grade and allowed regressions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/PSModule.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PSModule.yml b/.github/PSModule.yml index c807b64..81bb5b6 100644 --- a/.github/PSModule.yml +++ b/.github/PSModule.yml @@ -4,7 +4,7 @@ Test: CodeCoverage: - PercentTarget: 25 + PercentTarget: 80 # TestResults: # Skip: true # SourceCode: From 6087f96ed0b703667c4a662267b2cc9a23f9a00c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Aug 2026 03:16:54 +0200 Subject: [PATCH 2/2] Tighten bare Should -Throw assertions Add expected-message patterns to duplicate-key, undefined-alias, and resource-limit tests so failures are more diagnostic and match the documented error classifications. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- tests/ConvertFrom-Yaml.Tests.ps1 | 37 +++++++++++++++++++++----------- tests/ConvertTo-Yaml.Tests.ps1 | 32 +++++++++++++++++---------- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/tests/ConvertFrom-Yaml.Tests.ps1 b/tests/ConvertFrom-Yaml.Tests.ps1 index 232db45..24d2101 100644 --- a/tests/ConvertFrom-Yaml.Tests.ps1 +++ b/tests/ConvertFrom-Yaml.Tests.ps1 @@ -467,14 +467,18 @@ date: !!timestamp 2001-12-14 Context 'Validation and limits' { It 'rejects duplicate scalar, canonical numeric, and complex keys' { - { "key: one`nkey: two" | ConvertFrom-Yaml } | Should -Throw - { "1: one`n01: two" | ConvertFrom-Yaml -AsHashtable } | Should -Throw - { "1.0: one`n1.00: two" | ConvertFrom-Yaml -AsHashtable } | Should -Throw - { "1.0: one`n1e0: two" | ConvertFrom-Yaml -AsHashtable } | Should -Throw + { "key: one`nkey: two" | ConvertFrom-Yaml } | + Should -Throw -ExpectedMessage '*duplicate mapping key*' + { "1: one`n01: two" | ConvertFrom-Yaml -AsHashtable } | + Should -Throw -ExpectedMessage '*duplicate mapping key*' + { "1.0: one`n1.00: two" | ConvertFrom-Yaml -AsHashtable } | + Should -Throw -ExpectedMessage '*duplicate mapping key*' + { "1.0: one`n1e0: two" | ConvertFrom-Yaml -AsHashtable } | + Should -Throw -ExpectedMessage '*duplicate mapping key*' { "? [a, b]`n: one`n? [a, b]`n: two" | ConvertFrom-Yaml -AsHashtable } | - Should -Throw + Should -Throw -ExpectedMessage '*duplicate mapping key*' { "? {a: 1, A: 1}`n: one`n? {A: 1, a: 1}`n: two" | ConvertFrom-Yaml -AsHashtable } | - Should -Throw + Should -Throw -ExpectedMessage '*duplicate mapping key*' } It 'normalizes cross-type finite floats for key equality' { @@ -507,7 +511,8 @@ Context 'Validation and limits' { : two '@ - { $yaml | ConvertFrom-Yaml -AsHashtable } | Should -Throw + { $yaml | ConvertFrom-Yaml -AsHashtable } | + Should -Throw -ExpectedMessage '*duplicate mapping key*' ($yaml | Test-Yaml) | Should -BeFalse } @@ -519,7 +524,8 @@ Context 'Validation and limits' { : two '@ - { $yaml | ConvertFrom-Yaml -AsHashtable } | Should -Throw + { $yaml | ConvertFrom-Yaml -AsHashtable } | + Should -Throw -ExpectedMessage '*duplicate mapping key*' ($yaml | Test-Yaml) | Should -BeFalse } @@ -530,14 +536,19 @@ Context 'Validation and limits' { } It 'rejects undefined aliases' { - { 'value: *missing' | ConvertFrom-Yaml } | Should -Throw + { 'value: *missing' | ConvertFrom-Yaml } | + Should -Throw -ExpectedMessage '*does not refer to a preceding anchor*' } It 'enforces depth, node, alias, and scalar limits' { - { "a:`n b:`n c: value" | ConvertFrom-Yaml -Depth 2 } | Should -Throw - { "[one, two]" | ConvertFrom-Yaml -MaxNodes 2 } | Should -Throw - { "a: &a value`nb: *a" | ConvertFrom-Yaml -MaxAliases 0 } | Should -Throw - { 'value: long' | ConvertFrom-Yaml -MaxScalarLength 4 } | Should -Throw + { "a:`n b:`n c: value" | ConvertFrom-Yaml -Depth 2 } | + Should -Throw -ExpectedMessage '*configured limit of 2*' + { "[one, two]" | ConvertFrom-Yaml -MaxNodes 2 } | + Should -Throw -ExpectedMessage '*configured limit of 2 nodes*' + { "a: &a value`nb: *a" | ConvertFrom-Yaml -MaxAliases 0 } | + Should -Throw -ExpectedMessage '*configured limit of 0 aliases*' + { 'value: long' | ConvertFrom-Yaml -MaxScalarLength 4 } | + Should -Throw -ExpectedMessage '*configured limit of 4 characters*' } It 'enforces tag and numeric limits before expensive construction' { diff --git a/tests/ConvertTo-Yaml.Tests.ps1 b/tests/ConvertTo-Yaml.Tests.ps1 index 2796fca..6f43414 100644 --- a/tests/ConvertTo-Yaml.Tests.ps1 +++ b/tests/ConvertTo-Yaml.Tests.ps1 @@ -550,9 +550,12 @@ Describe 'ConvertTo-Yaml' { It 'enforces depth, node, and scalar limits without truncating' { $nested = [ordered]@{ a = [ordered]@{ b = [ordered]@{ c = 1 } } } - { $nested | ConvertTo-Yaml -Depth 2 } | Should -Throw - { @(1, 2) | ConvertTo-Yaml -MaxNodes 2 } | Should -Throw - { 'long' | ConvertTo-Yaml -MaxScalarLength 3 } | Should -Throw + { $nested | ConvertTo-Yaml -Depth 2 } | + Should -Throw -ExpectedMessage '*configured depth limit of 2*' + { @(1, 2) | ConvertTo-Yaml -MaxNodes 2 } | + Should -Throw -ExpectedMessage '*configured limit of 2 nodes*' + { 'long' | ConvertTo-Yaml -MaxScalarLength 3 } | + Should -Throw -ExpectedMessage '*configured limit of 3 characters*' } It 'stops infinite pipelines at the node budget' { @@ -649,15 +652,22 @@ Describe 'ConvertTo-Yaml' { It 'enforces the scalar limit for every emitted scalar kind' { $bigInteger = [System.Numerics.BigInteger]::Parse('12345') - { ConvertTo-Yaml -InputObject $null -MaxScalarLength 3 } | Should -Throw - { ConvertTo-Yaml -InputObject $true -MaxScalarLength 3 } | Should -Throw - { ConvertTo-Yaml -InputObject $bigInteger -MaxScalarLength 4 } | Should -Throw - { ConvertTo-Yaml -InputObject ([decimal] 12.5) -MaxScalarLength 3 } | Should -Throw - { ConvertTo-Yaml -InputObject ([double]::PositiveInfinity) -MaxScalarLength 3 } | Should -Throw - { ConvertTo-Yaml -InputObject ([datetime]::UtcNow) -MaxScalarLength 10 } | Should -Throw - { ConvertTo-Yaml -InputObject ([byte[]] @(1, 2, 3)) -MaxScalarLength 3 } | Should -Throw + { ConvertTo-Yaml -InputObject $null -MaxScalarLength 3 } | + Should -Throw -ExpectedMessage '*configured limit of 3 characters*' + { ConvertTo-Yaml -InputObject $true -MaxScalarLength 3 } | + Should -Throw -ExpectedMessage '*configured limit of 3 characters*' + { ConvertTo-Yaml -InputObject $bigInteger -MaxScalarLength 4 } | + Should -Throw -ExpectedMessage '*configured limit of 4 characters*' + { ConvertTo-Yaml -InputObject ([decimal] 12.5) -MaxScalarLength 3 } | + Should -Throw -ExpectedMessage '*configured limit of 3 characters*' + { ConvertTo-Yaml -InputObject ([double]::PositiveInfinity) -MaxScalarLength 3 } | + Should -Throw -ExpectedMessage '*configured limit of 3 characters*' + { ConvertTo-Yaml -InputObject ([datetime]::UtcNow) -MaxScalarLength 10 } | + Should -Throw -ExpectedMessage '*configured limit of 10 characters*' + { ConvertTo-Yaml -InputObject ([byte[]] @(1, 2, 3)) -MaxScalarLength 3 } | + Should -Throw -ExpectedMessage '*configured limit of 3 characters*' { ConvertTo-Yaml -InputObject ([DayOfWeek]::Monday) -EnumsAsStrings -MaxScalarLength 5 } | - Should -Throw + Should -Throw -ExpectedMessage '*configured limit of 5 characters*' } } }