Skip to content

Commit fd44f01

Browse files
Harden YAML merge policy coverage
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 92bf292 commit fd44f01

1 file changed

Lines changed: 65 additions & 2 deletions

File tree

tests/Merge-Yaml.Tests.ps1

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,21 @@ tail: base
228228
$entry.Value['second'] | Should -Be 2
229229
}
230230

231+
It 'does not merge unequal complex keys that share a candidate bucket' {
232+
$base = @'
233+
? [region, { port: 443 }]
234+
: first
235+
'@
236+
$overlay = @'
237+
? [zone, { port: 443 }]
238+
: second
239+
'@
240+
$result = Merge-Yaml $base, $overlay | ConvertFrom-Yaml -AsHashtable
241+
242+
$result.Count | Should -Be 2
243+
@($result.Values) | Should -Be @('first', 'second')
244+
}
245+
231246
It 'keeps YAML 1.1 merge syntax as ordinary mapping data' {
232247
$base = @'
233248
<<:
@@ -298,20 +313,22 @@ items:
298313
- one
299314
- key: value
300315
- !item tagged
316+
- !other tagged
301317
- &other { self: *other }
302318
- added
303319
'@
304320
$merged = Merge-Yaml $base, $overlay -SequenceAction Unique
305321
$result = $merged | ConvertFrom-Yaml -AsHashtable
306322
$facts = Get-MergeYamlGraphFact -Yaml $merged
307323

308-
$result['items'].Count | Should -Be 5
309-
$result['items'][4] | Should -Be 'added'
324+
$result['items'].Count | Should -Be 6
325+
$result['items'][5] | Should -Be 'added'
310326
[object]::ReferenceEquals(
311327
$result['items'][3],
312328
$result['items'][3]['self']
313329
) | Should -BeTrue
314330
@($facts.Tags) | Should -Contain '!item'
331+
@($facts.Tags) | Should -Contain '!other'
315332
}
316333

317334
It 'preserves overlay sharing and cycles while appending' {
@@ -363,6 +380,16 @@ items:
363380
Should -BeExactly ($base | Format-Yaml)
364381
}
365382

383+
It 'does not apply sequence actions across incompatible effective tags' {
384+
$failure = Get-MergeYamlFailure {
385+
Merge-Yaml '!first [one]', '!second [two]' `
386+
-SequenceAction Append -ConflictAction Error
387+
}
388+
389+
$failure.Exception.Data['YamlErrorId'] | Should -BeExactly 'YamlMergeConflict'
390+
$failure.Exception.Message | Should -Match 'sequence tag'
391+
}
392+
366393
It 'applies nested null replacement and ignoring' {
367394
$base = "root:`n value: retained"
368395
$overlay = "root:`n value: null"
@@ -471,6 +498,17 @@ node: &cycle
471498
$documents[1]['second'] | Should -Be 'overlay'
472499
}
473500

501+
It 'keeps explicit empty documents as positive document records' {
502+
$base = "---`nvalue: base`n---"
503+
$overlay = "---`nvalue: overlay`n---"
504+
$merged = Merge-Yaml $base, $overlay
505+
$documents = @($merged | ConvertFrom-Yaml -AsHashtable)
506+
507+
$documents.Count | Should -Be 2
508+
$documents[0]['value'] | Should -Be 'overlay'
509+
$documents[1] | Should -BeNullOrEmpty
510+
}
511+
474512
It 'rejects no-document streams with their zero-based input index' -ForEach @(
475513
@{ Empty = '' }
476514
@{ Empty = "# comment only`n" }
@@ -507,6 +545,31 @@ node: &cycle
507545
Should -Be 'YamlInvalidFlowCollection,Merge-Yaml'
508546
}
509547

548+
It 'preserves every parser resource classification' -ForEach @(
549+
@{ Yaml = "a:`n b:`n c: value"; Parameters = @{ Depth = 2 } }
550+
@{ Yaml = '[one, two]'; Parameters = @{ MaxNodes = 2 } }
551+
@{ Yaml = "a: &a value`nb: *a"; Parameters = @{ MaxAliases = 0 } }
552+
@{ Yaml = 'value: long'; Parameters = @{ MaxScalarLength = 4 } }
553+
@{ Yaml = '!long value'; Parameters = @{ MaxTagLength = 2 } }
554+
@{
555+
Yaml = "!a one`n---`n!b two"
556+
Parameters = @{ MaxTotalTagLength = 3 }
557+
}
558+
@{ Yaml = '123'; Parameters = @{ MaxNumericLength = 2 } }
559+
) {
560+
$parseFailure = Get-MergeYamlFailure {
561+
$Yaml | Format-Yaml @Parameters
562+
}
563+
$mergeFailure = Get-MergeYamlFailure {
564+
Merge-Yaml 'valid: true', $Yaml @Parameters
565+
}
566+
567+
$mergeFailure.Exception.Data['YamlErrorId'] |
568+
Should -BeExactly $parseFailure.Exception.Data['YamlErrorId']
569+
$mergeFailure.FullyQualifiedErrorId |
570+
Should -Be "$($parseFailure.Exception.Data['YamlErrorId']),Merge-Yaml"
571+
}
572+
510573
It 'enforces clone and result node budgets' {
511574
$failure = Get-MergeYamlFailure {
512575
Merge-Yaml 'a: 1', 'b: 2' -MaxNodes 3

0 commit comments

Comments
 (0)