Skip to content

Commit 033b9ff

Browse files
Merge latest conversion foundation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2 parents eb23a1c + 94879ad commit 033b9ff

7 files changed

Lines changed: 180 additions & 38 deletions

File tree

.github/PSModule.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
Test:
66
CodeCoverage:
7-
PercentTarget: 50
7+
PercentTarget: 25
88
# TestResults:
99
# Skip: true
1010
# SourceCode:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
#Requires -Version 7.6
22
#Requires -PSEdition Core
3+
[CmdletBinding()]
4+
param()

tests/Conformance.Tests.ps1

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,42 @@ Describe 'Released yaml-test-suite corpus accounting' {
109109
)
110110
}
111111

112+
It 'does not mask altered JSON values as projection policy' {
113+
$mutatedSuitePath = Join-Path $TestDrive 'mutated-policy-cases'
114+
$null = New-Item -Path $mutatedSuitePath -ItemType Directory -Force
115+
foreach ($case in @('565N', 'J7PZ')) {
116+
Copy-Item -LiteralPath (Join-Path $suiteDataPath $case) `
117+
-Destination $mutatedSuitePath -Recurse
118+
}
119+
120+
$binaryJsonPath = Join-Path $mutatedSuitePath '565N\in.json'
121+
$binaryJson = Get-Content -LiteralPath $binaryJsonPath -Raw |
122+
ConvertFrom-Json -AsHashtable
123+
$binaryJson['description'] = 'Altered expected value'
124+
$binaryJson | ConvertTo-Json -Depth 10 |
125+
Set-Content -LiteralPath $binaryJsonPath -Encoding utf8NoBOM
126+
127+
$orderedMapJsonPath = Join-Path $mutatedSuitePath 'J7PZ\in.json'
128+
$orderedMapJson = Get-Content -LiteralPath $orderedMapJsonPath -Raw |
129+
ConvertFrom-Json -AsHashtable
130+
$orderedMapJson[0]['Mark McGwire'] = 66
131+
$orderedMapJson | ConvertTo-Json -Depth 10 |
132+
Set-Content -LiteralPath $orderedMapJsonPath -Encoding utf8NoBOM
133+
134+
$mutatedResults = @(
135+
& (Join-Path $PSScriptRoot 'tools\Invoke-YamlTestSuite.ps1') `
136+
-Path $mutatedSuitePath `
137+
-CompareJson
138+
)
139+
@($mutatedResults | Sort-Object Case | Select-Object -ExpandProperty Case) |
140+
Should -Be @('565N', 'J7PZ')
141+
@($mutatedResults | Where-Object JsonResult -EQ 'PolicyDifference').Count |
142+
Should -Be 0
143+
@($mutatedResults | Where-Object JsonResult -EQ 'Fail').Count | Should -Be 2
144+
@($mutatedResults.JsonReason | Select-Object -Unique) |
145+
Should -Be @('ConstructedValueMismatch')
146+
}
147+
112148
It 'accounts for out.yaml representation comparisons' {
113149
@($suiteResults | Where-Object OutYamlResult -EQ 'Pass').Count | Should -Be 241
114150
@($suiteResults | Where-Object OutYamlResult -EQ 'PolicyDifference').Count |

tests/Packaging.Tests.ps1

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,15 @@
1111
[CmdletBinding()]
1212
param()
1313

14-
$importedYamlCommand = Get-Command -Name ConvertFrom-Yaml -ErrorAction SilentlyContinue
14+
$importedYamlModule = Get-Module -Name Yaml | Select-Object -First 1
1515
$skipArtifactTests = [string]::IsNullOrWhiteSpace($env:PSMODULE_YAML_TEST_ARTIFACT) -and (
16-
$null -eq $importedYamlCommand -or $importedYamlCommand.ModuleName -ne 'Yaml'
16+
$null -eq $importedYamlModule
1717
)
1818

1919
BeforeAll {
2020
. (Join-Path $PSScriptRoot 'TestBootstrap.ps1')
2121
$repositoryRoot = Split-Path -Parent $PSScriptRoot
22-
$loadedYamlModule = if (-not [string]::IsNullOrWhiteSpace(
23-
$env:PSMODULE_YAML_TEST_ARTIFACT
24-
)) {
25-
Import-Module -Name $env:PSMODULE_YAML_TEST_ARTIFACT -Force -Global -PassThru `
26-
-ErrorAction Stop |
27-
Where-Object Name -EQ 'Yaml' |
28-
Select-Object -First 1
29-
} else {
30-
$command = Get-Command -Name ConvertFrom-Yaml -ErrorAction SilentlyContinue
31-
if ($null -ne $command -and $command.ModuleName -eq 'Yaml') {
32-
$command.Module
33-
} else {
34-
$null
35-
}
36-
}
22+
$loadedYamlModule = $yamlModule
3723
$artifactManifestPath = if ($null -ne $loadedYamlModule) {
3824
Join-Path $loadedYamlModule.ModuleBase 'Yaml.psd1'
3925
} else {
@@ -63,8 +49,8 @@ Describe 'Dependency-free package source' {
6349
$manifest.ContainsKey('RequiredAssemblies') | Should -BeFalse
6450
}
6551

66-
It 'declares the generated artifact runtime once in module initialization' {
67-
$requirementPath = Join-Path $repositoryRoot 'src\init\requirements.ps1'
52+
It 'declares the generated artifact runtime once in the module header' {
53+
$requirementPath = Join-Path $repositoryRoot 'src\header.ps1'
6854
$source = Get-Content -LiteralPath $requirementPath -Raw
6955

7056
$source | Should -Match '(?m)^#Requires -Version 7\.6\r?$'
@@ -164,8 +150,8 @@ Describe 'Generated artifact package' {
164150
$script = @'
165151
$ErrorActionPreference = 'Stop'
166152
$ps = $PSVersionTable.PSVersion
167-
if ($ps.Major -ne 7 -or $ps.Minor -ne 6) {
168-
throw "Expected PowerShell 7.6.x but got $ps."
153+
if ($ps -lt [version] '7.6') {
154+
throw "Expected PowerShell 7.6 or newer but got $ps."
169155
}
170156
if ($PSVersionTable.PSEdition -cne 'Core') {
171157
throw "Expected PowerShell Core but got $($PSVersionTable.PSEdition)."
@@ -212,7 +198,13 @@ if (-not (Test-Yaml -Yaml $deepYaml -Depth 128 -MaxNodes 300)) {
212198
$runtime = $output | Where-Object { $_ -like 'powershell-runtime=*' } |
213199
Select-Object -Last 1
214200

215-
$runtime | Should -Match '^powershell-runtime=7\.6\.\d+;edition=Core$'
201+
$runtimeMatch = [regex]::Match(
202+
[string] $runtime,
203+
'^powershell-runtime=(?<Version>\d+(?:\.\d+){1,3});edition=Core$'
204+
)
205+
$runtimeMatch.Success | Should -BeTrue
206+
([version] $runtimeMatch.Groups['Version'].Value) -lt [version] '7.6' |
207+
Should -BeFalse
216208
Write-Information -MessageData $runtime -InformationAction Continue
217209
$LASTEXITCODE | Should -Be 0
218210
}

tests/Specification.Tests.ps1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ Describe 'Pinned yaml-test-suite reference cases' {
204204
) | Should -BeTrue
205205
, $result.canonical | Should -BeOfType [byte[]]
206206
, $result.generic | Should -BeOfType [byte[]]
207+
[System.Convert]::ToHexString(
208+
[System.Security.Cryptography.SHA256]::HashData($result.canonical)
209+
) | Should -Be '0DD8F84D24840A21A56495526E5B227911D13389109C62194A64B6CCBF3B1400'
207210
}
208211

209212
It 'projects the legacy ordered map in case J7PZ as an ordered dictionary' {

tests/TestBootstrap.ps1

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
$artifactManifestOverride = $env:PSMODULE_YAML_TEST_ARTIFACT
22
$yamlModule = $null
33
if (-not [string]::IsNullOrWhiteSpace($artifactManifestOverride)) {
4-
$yamlModule = Import-Module -Name $artifactManifestOverride -Force -Global -PassThru `
5-
-ErrorAction Stop |
6-
Where-Object Name -EQ 'Yaml' |
4+
$resolvedArtifactManifestPath = (
5+
Resolve-Path -LiteralPath $artifactManifestOverride -ErrorAction Stop
6+
).Path
7+
$artifactModuleBase = Split-Path -Parent $resolvedArtifactManifestPath
8+
$yamlModule = Get-Module -Name Yaml |
9+
Where-Object ModuleBase -EQ $artifactModuleBase |
710
Select-Object -First 1
11+
if ($null -eq $yamlModule) {
12+
$yamlModule = Import-Module -Name $resolvedArtifactManifestPath -Force -Global -PassThru `
13+
-ErrorAction Stop |
14+
Where-Object Name -EQ 'Yaml' |
15+
Select-Object -First 1
16+
}
817
}
918

1019
if ($null -eq $yamlModule) {
11-
$yamlCommand = Get-Command -Name ConvertFrom-Yaml -ErrorAction SilentlyContinue
12-
$yamlModule = if (
13-
$null -ne $yamlCommand -and
14-
$yamlCommand.ModuleName -eq 'Yaml' -and
15-
$yamlCommand.CommandType -eq 'Function'
16-
) {
17-
$yamlCommand.Module
18-
}
20+
$yamlModule = Get-Module -Name Yaml | Select-Object -First 1
1921
}
2022

2123
if ($null -eq $yamlModule) {

tests/tools/Invoke-YamlTestSuite.ps1

Lines changed: 111 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,18 +242,123 @@ function ConvertTo-YamlSuiteReferenceSignature {
242242
return ($output -join ';')
243243
}
244244

245+
function Test-YamlSuiteBinaryByteArrayProjection {
246+
[OutputType([bool])]
247+
param (
248+
[Parameter(Mandatory)]
249+
[object[]] $ExpectedValues,
250+
251+
[Parameter(Mandatory)]
252+
[object[]] $ActualValues
253+
)
254+
255+
if ($ExpectedValues.Count -ne 1 -or $ActualValues.Count -ne 1) {
256+
return $false
257+
}
258+
$expectedDocument = $ExpectedValues[0]
259+
$actualDocument = $ActualValues[0]
260+
if ($expectedDocument -isnot [System.Collections.IDictionary] -or
261+
$actualDocument -isnot [System.Collections.IDictionary] -or
262+
$expectedDocument.Count -ne 3 -or $actualDocument.Count -ne 3) {
263+
return $false
264+
}
265+
266+
foreach ($key in @('canonical', 'generic', 'description')) {
267+
if (-not $expectedDocument.Contains($key) -or -not $actualDocument.Contains($key)) {
268+
return $false
269+
}
270+
}
271+
if ($expectedDocument['description'] -isnot [string] -or
272+
$actualDocument['description'] -isnot [string] -or
273+
$actualDocument['description'] -cne $expectedDocument['description']) {
274+
return $false
275+
}
276+
277+
foreach ($key in @('canonical', 'generic')) {
278+
if ($expectedDocument[$key] -isnot [string] -or
279+
$actualDocument[$key] -isnot [byte[]]) {
280+
return $false
281+
}
282+
$expectedBase64 = $expectedDocument[$key] -replace '\s', ''
283+
$expectedBytes = [System.Convert]::FromBase64String($expectedBase64)
284+
if (-not [System.Linq.Enumerable]::SequenceEqual[byte](
285+
$expectedBytes,
286+
[byte[]] $actualDocument[$key]
287+
)) {
288+
return $false
289+
}
290+
}
291+
return $true
292+
}
293+
294+
function Test-YamlSuiteLegacyOrderedMapProjection {
295+
[OutputType([bool])]
296+
param (
297+
[Parameter(Mandatory)]
298+
[object[]] $ExpectedValues,
299+
300+
[Parameter(Mandatory)]
301+
[object[]] $ActualValues
302+
)
303+
304+
if ($ExpectedValues.Count -ne 1 -or $ActualValues.Count -ne 1 -or
305+
$ExpectedValues[0] -is [System.Collections.IDictionary] -or
306+
$ExpectedValues[0] -isnot [System.Collections.IEnumerable] -or
307+
$ActualValues[0] -isnot [System.Collections.Specialized.OrderedDictionary]) {
308+
return $false
309+
}
310+
311+
$expectedEntries = @($ExpectedValues[0])
312+
$actualDocument = $ActualValues[0]
313+
$actualKeys = @($actualDocument.Keys)
314+
if ($expectedEntries.Count -ne $actualDocument.Count) {
315+
return $false
316+
}
317+
for ($index = 0; $index -lt $expectedEntries.Count; $index++) {
318+
$expectedEntry = $expectedEntries[$index]
319+
if ($expectedEntry -isnot [System.Collections.IDictionary] -or
320+
$expectedEntry.Count -ne 1) {
321+
return $false
322+
}
323+
$expectedKey = @($expectedEntry.Keys)[0]
324+
if ($expectedKey -isnot [string] -or $actualKeys[$index] -cne $expectedKey -or
325+
(ConvertTo-YamlSuiteCanonicalValue -Value $actualDocument[$expectedKey]) -cne
326+
(ConvertTo-YamlSuiteCanonicalValue -Value $expectedEntry[$expectedKey])) {
327+
return $false
328+
}
329+
}
330+
return $true
331+
}
332+
245333
function Get-YamlSuiteJsonPolicyReason {
246334
[OutputType([string])]
247335
param (
248336
[Parameter(Mandatory)]
249-
[string] $Case
337+
[string] $Case,
338+
339+
[Parameter(Mandatory)]
340+
[object[]] $ExpectedValues,
341+
342+
[Parameter(Mandatory)]
343+
[object[]] $ActualValues
250344
)
251345

252346
switch -CaseSensitive ($Case) {
253-
'565N' { return 'BinaryByteArrayProjection' }
254-
'J7PZ' { return 'LegacyOrderedMapProjection' }
347+
'565N' {
348+
if (Test-YamlSuiteBinaryByteArrayProjection -ExpectedValues $ExpectedValues `
349+
-ActualValues $ActualValues) {
350+
return 'BinaryByteArrayProjection'
351+
}
352+
}
353+
'J7PZ' {
354+
if (Test-YamlSuiteLegacyOrderedMapProjection -ExpectedValues $ExpectedValues `
355+
-ActualValues $ActualValues) {
356+
return 'LegacyOrderedMapProjection'
357+
}
358+
}
255359
default { return '' }
256360
}
361+
return ''
257362
}
258363

259364
function ConvertFrom-YamlSuiteEventText {
@@ -746,7 +851,9 @@ foreach ($inputFile in $inputFiles) {
746851
if ($projectedCanonical -ceq $expectedCanonical) {
747852
$jsonResult = 'Pass'
748853
} else {
749-
$reason = Get-YamlSuiteJsonPolicyReason -Case $casePath
854+
$reason = Get-YamlSuiteJsonPolicyReason -Case $casePath `
855+
-ExpectedValues ([object[]] $expectedValues.ToArray()) `
856+
-ActualValues ([object[]] $projectedValues)
750857
if ($reason) {
751858
$jsonResult = 'PolicyDifference'
752859
$jsonReason = $reason

0 commit comments

Comments
 (0)