mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-02 10:31:40 +00:00
When explode resolves merge anchors (<<:), items copied from the alias target retained the original parent pointer instead of being set to the enclosing node being reconstructed. This caused GetPath() to return wrong paths for children of merge-anchored nodes, making subsequent merge operations target the wrong LHS keys. In fixedReconstructAliasedMap, set copied.Parent = node after copy. In reconstructAliasedMap (non-spec path), replace AddChild (which creates sequence-style numeric-index entries) with AddKeyValueChild to properly reconstruct mapping key-value pairs. AddKeyValueChild also correctly sets parent references via SetParent.
609 lines
18 KiB
Go
609 lines
18 KiB
Go
package yqlib
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
var specDocument = `- &CENTRE { x: 1, y: 2 }
|
|
- &LEFT { x: 0, y: 2 }
|
|
- &BIG { r: 10 }
|
|
- &SMALL { r: 1 }
|
|
`
|
|
|
|
var expectedSpecResult = "D0, P[4], (!!map)::x: 1\ny: 2\nr: 10\n"
|
|
|
|
var simpleArrayRef = `item_value: &item_value
|
|
value: true
|
|
|
|
thingOne:
|
|
name: item_1
|
|
<<: *item_value
|
|
|
|
thingTwo:
|
|
name: item_2
|
|
<<: *item_value
|
|
`
|
|
|
|
var expectedUpdatedArrayRef = `D0, P[], (!!map)::item_value: &item_value
|
|
value: true
|
|
thingOne:
|
|
name: item_1
|
|
value: false
|
|
thingTwo:
|
|
name: item_2
|
|
<<: *item_value
|
|
`
|
|
|
|
var explodeMergeAnchorsFixedExpected = `D0, P[], (!!map)::foo:
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar:
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: foobarList_b
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foobarList_c
|
|
foobar:
|
|
c: foobar_c
|
|
a: foo_a
|
|
thing: foobar_thing
|
|
`
|
|
|
|
var explodeMergeAnchorsExpected = `D0, P[], (!!map)::foo:
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar:
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: bar_b
|
|
thing: foo_thing
|
|
c: foobarList_c
|
|
a: foo_a
|
|
foobar:
|
|
c: foo_c
|
|
a: foo_a
|
|
thing: foobar_thing
|
|
`
|
|
|
|
var explodeWhenKeysExistDocument = `objects:
|
|
- &circle
|
|
name: circle
|
|
shape: round
|
|
- name: ellipse
|
|
!!merge <<: *circle
|
|
- !!merge <<: *circle
|
|
name: egg
|
|
`
|
|
|
|
var explodeWhenKeysExistLegacy = `D0, P[], (!!map)::objects:
|
|
- name: circle
|
|
shape: round
|
|
- name: circle
|
|
shape: round
|
|
- shape: round
|
|
name: egg
|
|
`
|
|
|
|
var explodeWhenKeysExistExpected = `D0, P[], (!!map)::objects:
|
|
- name: circle
|
|
shape: round
|
|
- name: ellipse
|
|
shape: round
|
|
- shape: round
|
|
name: egg
|
|
`
|
|
|
|
var fixedAnchorOperatorScenarios = []expressionScenario{
|
|
{
|
|
skipDoc: true,
|
|
description: "merge anchor after existing keys",
|
|
subdescription: "Does not override existing keys - note the name field in the second element is still ellipse.",
|
|
document: explodeWhenKeysExistDocument,
|
|
expression: "explode(.)",
|
|
expected: []string{explodeWhenKeysExistExpected},
|
|
},
|
|
{
|
|
description: "FIXED: Explode with merge anchors",
|
|
subdescription: "Observe that foobarList.b property is still foobarList_b.",
|
|
document: mergeDocSample,
|
|
expression: `explode(.)`,
|
|
expected: []string{explodeMergeAnchorsFixedExpected},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
document: mergeDocSample,
|
|
expression: `.foo* | explode(.) | (. style="flow")`,
|
|
expected: []string{
|
|
"D0, P[foo], (!!map)::{a: foo_a, thing: foo_thing, c: foo_c}\n",
|
|
"D0, P[foobarList], (!!map)::{b: foobarList_b, a: foo_a, thing: foo_thing, c: foobarList_c}\n",
|
|
"D0, P[foobar], (!!map)::{c: foobar_c, a: foo_a, thing: foobar_thing}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
document: mergeDocSample,
|
|
expression: `.foo* | explode(explode(.)) | (. style="flow")`,
|
|
expected: []string{
|
|
"D0, P[foo], (!!map)::{a: foo_a, thing: foo_thing, c: foo_c}\n",
|
|
"D0, P[foobarList], (!!map)::{b: foobarList_b, a: foo_a, thing: foo_thing, c: foobarList_c}\n",
|
|
"D0, P[foobar], (!!map)::{c: foobar_c, a: foo_a, thing: foobar_thing}\n",
|
|
},
|
|
},
|
|
{
|
|
description: "FIXED: Merge multiple maps",
|
|
subdescription: "Taken from https://yaml.org/type/merge.html. Same values as legacy, but with the correct key order.",
|
|
document: specDocument + "- << : [ *CENTRE, *BIG ]\n",
|
|
expression: ".[4] | explode(.)",
|
|
expected: []string{"D0, P[4], (!!map)::x: 1\ny: 2\nr: 10\n"},
|
|
},
|
|
{
|
|
description: "FIXED: Override",
|
|
subdescription: "Taken from https://yaml.org/type/merge.html. Same values as legacy, but with the correct key order.",
|
|
document: specDocument + "- << : [ *BIG, *LEFT, *SMALL ]\n x: 1\n",
|
|
expression: ".[4] | explode(.)",
|
|
expected: []string{"D0, P[4], (!!map)::r: 10\ny: 2\nx: 1\n"},
|
|
},
|
|
{
|
|
description: "Exploding inline merge anchor",
|
|
// subdescription: "`<<` map must be exploded, otherwise `c: *b` will become invalid",
|
|
document: `{a: {b: &b 42}, <<: {c: *b}}`,
|
|
expression: `explode(.) | sort_keys(.)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{a: {b: 42}, c: 42}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "Exploding inline merge anchor in sequence",
|
|
subdescription: "`<<` map must be exploded, otherwise `c: *b` will become invalid",
|
|
document: `{a: {b: &b 42}, <<: [{c: *b}]}`,
|
|
expression: `explode(.) | sort_keys(.)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{a: {b: 42}, c: 42}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "Exploding merge anchor should not explode neighbours",
|
|
subdescription: "b must not be exploded, as `r: *a` will become invalid",
|
|
document: `{b: &b {a: &a 42}, r: *a, c: {<<: *b}}`,
|
|
expression: `explode(.c)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{b: &b {a: &a 42}, r: *a, c: {a: 42}}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "Exploding sequence merge anchor should not explode neighbours",
|
|
subdescription: "b must not be exploded, as `r: *a` will become invalid",
|
|
document: `{b: &b {a: &a 42}, r: *a, c: {<<: [*b]}}`,
|
|
expression: `explode(.c)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{b: &b {a: &a 42}, r: *a, c: {a: 42}}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "Merge anchor with inline map",
|
|
document: `{<<: {a: 42}}`,
|
|
expression: `explode(.)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{a: 42}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "Nested merge anchor with inline map",
|
|
document: `{<<: {<<: {a: 42}}}`,
|
|
expression: `explode(.)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{a: 42}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "Merge anchor with sequence with inline map",
|
|
document: `{<<: [{a: 42}]}`,
|
|
expression: `explode(.)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{a: 42}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "Merge anchor with aliased sequence with inline map",
|
|
document: `{s: &s [{a: 42}], m: {<<: *s}}`,
|
|
expression: `.m | explode(.)`,
|
|
expected: []string{
|
|
"D0, P[m], (!!map)::{a: 42}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "deleting after explode",
|
|
document: "x: 37\na: &a\n b: 42\n<<: *a",
|
|
expression: `explode(.) | del(.x)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::a:\n b: 42\nb: 42\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "Merge after explode preserves correct parent references",
|
|
document: `opensearch: &opensearch-cluster
|
|
ip2geo:
|
|
enabled: false
|
|
|
|
opensearch-client:
|
|
<<: *opensearch-cluster
|
|
nodeGroup: client
|
|
opensearchJavaOpts: "-Xmx1024m -Xms1024m"`,
|
|
document2: `opensearch: &opensearch-cluster
|
|
ip2geo:
|
|
enabled: true
|
|
|
|
opensearch-client:
|
|
<<: *opensearch-cluster
|
|
opensearchJavaOpts: "-Xmx1536m -Xms1536m"`,
|
|
expression: `(select(fi == 0) | explode(.)) * (select(fi == 1) | explode(.))`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::opensearch:\n ip2geo:\n enabled: true\nopensearch-client:\n ip2geo:\n enabled: true\n nodeGroup: client\n opensearchJavaOpts: \"-Xmx1536m -Xms1536m\"\n",
|
|
},
|
|
},
|
|
}
|
|
|
|
var badAnchorOperatorScenarios = []expressionScenario{
|
|
{
|
|
skipDoc: true, // incorrect overrides
|
|
description: "LEGACY: merge anchor after existing keys",
|
|
document: explodeWhenKeysExistDocument,
|
|
expression: "explode(.)",
|
|
expected: []string{explodeWhenKeysExistLegacy},
|
|
},
|
|
{
|
|
description: "LEGACY: Explode with merge anchors", // incorrect overrides
|
|
subdescription: "Caution: this is for when --yaml-fix-merge-anchor-to-spec=false; it's not to YAML spec because the merge anchors incorrectly override the object values (foobarList.b is set to bar_b when it should still be foobarList_b). Flag will default to true in late 2025",
|
|
document: mergeDocSample,
|
|
expression: `explode(.)`,
|
|
expected: []string{explodeMergeAnchorsExpected},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
document: mergeDocSample, // incorrect overrides
|
|
expression: `.foo* | explode(.) | (. style="flow")`,
|
|
expected: []string{
|
|
"D0, P[foo], (!!map)::{a: foo_a, thing: foo_thing, c: foo_c}\n",
|
|
"D0, P[foobarList], (!!map)::{b: bar_b, thing: foo_thing, c: foobarList_c, a: foo_a}\n",
|
|
"D0, P[foobar], (!!map)::{c: foo_c, a: foo_a, thing: foobar_thing}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
document: mergeDocSample,
|
|
expression: `.foo* | explode(explode(.)) | (. style="flow")`,
|
|
expected: []string{
|
|
"D0, P[foo], (!!map)::{a: foo_a, thing: foo_thing, c: foo_c}\n",
|
|
"D0, P[foobarList], (!!map)::{b: bar_b, thing: foo_thing, c: foobarList_c, a: foo_a}\n",
|
|
"D0, P[foobar], (!!map)::{c: foo_c, a: foo_a, thing: foobar_thing}\n",
|
|
},
|
|
},
|
|
{
|
|
description: "LEGACY: Merge multiple maps",
|
|
subdescription: "see https://yaml.org/type/merge.html. This has the correct data, but the wrong key order; set --yaml-fix-merge-anchor-to-spec=true to fix the key order.",
|
|
document: specDocument + "- << : [ *CENTRE, *BIG ]\n",
|
|
expression: ".[4] | explode(.)",
|
|
expected: []string{"D0, P[4], (!!map)::r: 10\nx: 1\ny: 2\n"},
|
|
},
|
|
{
|
|
description: "LEGACY: Override",
|
|
subdescription: "see https://yaml.org/type/merge.html. This has the correct data, but the wrong key order; set --yaml-fix-merge-anchor-to-spec=true to fix the key order.",
|
|
|
|
document: specDocument + "- << : [ *BIG, *LEFT, *SMALL ]\n x: 1\n",
|
|
expression: ".[4] | explode(.)",
|
|
expected: []string{"D0, P[4], (!!map)::r: 10\nx: 1\ny: 2\n"},
|
|
},
|
|
}
|
|
|
|
var mixedMergeTagStyleDocument = `
|
|
constants:
|
|
errorResponse: &errorResponse
|
|
status: 200
|
|
endpoints:
|
|
- condition: true
|
|
!!merge <<: *errorResponse
|
|
- condition: false
|
|
<<: *errorResponse
|
|
other:
|
|
!!merge <<: *errorResponse
|
|
somethingElse:
|
|
<<: *errorResponse
|
|
`
|
|
|
|
var mixedMergeTagStyleExplodedDocument = `
|
|
constants:
|
|
errorResponse:
|
|
status: 200
|
|
endpoints:
|
|
- condition: true
|
|
status: 200
|
|
- condition: false
|
|
status: 200
|
|
other:
|
|
status: 200
|
|
somethingElse:
|
|
status: 200
|
|
`
|
|
|
|
var anchorOperatorScenarios = []expressionScenario{
|
|
{
|
|
// mergeObjects previously skipped all !!merge-tagged nodes. Since !!merge only appears on
|
|
// << map keys, this meant applyAssignment was never called for the << key. It was later
|
|
// autocreated by createStringScalarNode("<<") with tag !!str, silently dropping !!merge.
|
|
// DontFollowAlias:true already prevents aliases being followed, so the skip was redundant.
|
|
// Old (buggy) output: "D0, P[], (!!map)::base: &base\n x: 1\ndest:\n <<: *base\n"
|
|
skipDoc: true,
|
|
description: "direct *+ preserves explicit !!merge tag on << key (regression for issue 2677)",
|
|
document: "base: &base\n x: 1\ndest:\n !!merge <<: *base\n",
|
|
expression: `. as $d | {} *+ $d`,
|
|
expected: []string{"D0, P[], (!!map)::base: &base\n x: 1\ndest:\n !!merge <<: *base\n"},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "explicit !!merge tag on << key is preserved through ireduce merge",
|
|
document: mixedMergeTagStyleDocument,
|
|
expression: `. as $item ireduce ({}; . *+ $item)`,
|
|
expected: []string{"D0, P[], (!!map)::" + mixedMergeTagStyleDocument},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "explode expands << merge keys regardless of explicit tag style (!!merge or plain)",
|
|
document: mixedMergeTagStyleDocument,
|
|
expression: `explode(.)`,
|
|
expected: []string{"D0, P[], (!!map)::" + mixedMergeTagStyleExplodedDocument},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "merge anchor to alias alias",
|
|
document: "b: &b 10\na: &a { k: *b }\nc:\n <<: [*a]",
|
|
expression: "explode(.)",
|
|
expected: []string{"D0, P[], (!!map)::b: 10\na: {k: 10}\nc:\n k: 10\n"},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "merge anchor not map",
|
|
document: "a: &a\n - 0\nc:\n <<: [*a]\n",
|
|
expectedError: "can only use merge anchors with maps (!!map) or sequences (!!seq) of maps, but got sequence containing !!seq",
|
|
expression: "explode(.)",
|
|
},
|
|
{
|
|
description: "Merge one map",
|
|
subdescription: "see https://yaml.org/type/merge.html",
|
|
document: specDocument + "- << : *CENTRE\n r: 10\n",
|
|
expression: ".[4] | explode(.)",
|
|
expected: []string{expectedSpecResult},
|
|
},
|
|
|
|
{
|
|
description: "Get anchor",
|
|
document: `a: &billyBob cat`,
|
|
expression: `.a | anchor`,
|
|
expected: []string{
|
|
"D0, P[a], (!!str)::billyBob\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Set anchor",
|
|
document: `a: cat`,
|
|
expression: `.a anchor = "foobar"`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::a: &foobar cat\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Set anchor relatively using assign-update",
|
|
document: `a: {b: cat}`,
|
|
expression: `.a anchor |= .b`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::a: &cat {b: cat}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
document: `a: {c: cat}`,
|
|
expression: `.a anchor |= .b`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::a: {c: cat}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
document: `a: {c: cat}`,
|
|
expression: `.a anchor = .b`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::a: {c: cat}\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Get alias",
|
|
document: `{b: &billyBob meow, a: *billyBob}`,
|
|
expression: `.a | alias`,
|
|
expected: []string{
|
|
"D0, P[a], (!!str)::billyBob\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Set alias",
|
|
document: `{b: &meow purr, a: cat}`,
|
|
expression: `.a alias = "meow"`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{b: &meow purr, a: *meow}\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Set alias to blank does nothing",
|
|
document: `{b: &meow purr, a: cat}`,
|
|
expression: `.a alias = ""`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{b: &meow purr, a: cat}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
document: `{b: &meow purr, a: cat}`,
|
|
expression: `.a alias = .c`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{b: &meow purr, a: cat}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
document: `{b: &meow purr, a: cat}`,
|
|
expression: `.a alias |= .c`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{b: &meow purr, a: cat}\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Set alias relatively using assign-update",
|
|
document: `{b: &meow purr, a: {f: meow}}`,
|
|
expression: `.a alias |= .f`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{b: &meow purr, a: *meow}\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Dont explode alias and anchor - check alias parent",
|
|
skipDoc: true,
|
|
document: `{a: &a [1], b: *a}`,
|
|
expression: `.b[]`,
|
|
expected: []string{
|
|
"D0, P[a 0], (!!int)::1\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Explode alias and anchor - check alias parent",
|
|
skipDoc: true,
|
|
document: `{a: &a cat, b: *a}`,
|
|
expression: `explode(.) | .b`,
|
|
expected: []string{
|
|
"D0, P[b], (!!str)::cat\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Explode splat",
|
|
skipDoc: true,
|
|
document: `{a: &a cat, b: *a}`,
|
|
expression: `explode(.)[]`,
|
|
expected: []string{
|
|
"D0, P[a], (!!str)::cat\n",
|
|
"D0, P[b], (!!str)::cat\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Explode alias and anchor - check original parent",
|
|
skipDoc: true,
|
|
document: `{a: &a cat, b: *a}`,
|
|
expression: `explode(.) | .a`,
|
|
expected: []string{
|
|
"D0, P[a], (!!str)::cat\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Explode alias and anchor",
|
|
document: `{f : {a: &a cat, b: *a}}`,
|
|
expression: `explode(.f)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{f: {a: cat, b: cat}}\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Explode with no aliases or anchors",
|
|
document: `a: mike`,
|
|
expression: `explode(.a)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::a: mike\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Explode with alias keys",
|
|
subdescription: "No space between alias",
|
|
skipDoc: true,
|
|
document: `{f : {a: &a cat, *a: b}}`,
|
|
expression: `explode(.f)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{f: {a: cat, cat: b}}\n",
|
|
},
|
|
skipForGoccy: true, // can't handle no space between alias
|
|
},
|
|
{
|
|
description: "Explode with alias keys",
|
|
document: `{f : {a: &a cat, *a : b}}`,
|
|
expression: `explode(.f)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{f: {a: cat, cat: b}}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
document: `{f : {a: &a cat, b: &b {foo: *a}, *a: *b}}`,
|
|
expression: `explode(.f)`,
|
|
expected: []string{
|
|
"D0, P[], (!!map)::{f: {a: cat, b: {foo: cat}, cat: {foo: cat}}}\n",
|
|
},
|
|
},
|
|
{
|
|
description: "Dereference and update a field",
|
|
subdescription: "Use explode with multiply to dereference an object",
|
|
document: simpleArrayRef,
|
|
expression: `.thingOne |= (explode(.) | sort_keys(.)) * {"value": false}`,
|
|
expected: []string{expectedUpdatedArrayRef},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "Duplicate keys",
|
|
subdescription: "outside merge anchor",
|
|
document: `{a: 1, a: 2}`,
|
|
expression: `explode(.)`,
|
|
expected: []string{
|
|
// {a: 2} would also be fine
|
|
"D0, P[], (!!map)::{a: 1, a: 2}\n",
|
|
},
|
|
},
|
|
{
|
|
skipDoc: true,
|
|
description: "!!str << should not be treated as merge anchor",
|
|
document: `{!!str <<: {a: 37}}`,
|
|
expression: `explode(.).a`,
|
|
expected: []string{
|
|
"D0, P[a], (!!null)::null\n",
|
|
},
|
|
},
|
|
}
|
|
|
|
func TestAnchorAliasOperatorScenarios(t *testing.T) {
|
|
for _, tt := range append(anchorOperatorScenarios, badAnchorOperatorScenarios...) {
|
|
testScenario(t, &tt)
|
|
}
|
|
documentOperatorScenarios(t, "anchor-and-alias-operators", append(anchorOperatorScenarios, badAnchorOperatorScenarios...))
|
|
}
|
|
|
|
func TestAnchorAliasOperatorAlignedToSpecScenarios(t *testing.T) {
|
|
ConfiguredYamlPreferences.FixMergeAnchorToSpec = true
|
|
for _, tt := range append(fixedAnchorOperatorScenarios, anchorOperatorScenarios...) {
|
|
testScenario(t, &tt)
|
|
}
|
|
|
|
for i, tt := range fixedAnchorOperatorScenarios {
|
|
fixedAnchorOperatorScenarios[i].subdescription = "Set `--yaml-fix-merge-anchor-to-spec=true` to get this correct merge behaviour (flag will default to true in late 2025).\n" + tt.subdescription
|
|
}
|
|
appendOperatorDocumentScenario(t, "anchor-and-alias-operators", fixedAnchorOperatorScenarios)
|
|
ConfiguredYamlPreferences.FixMergeAnchorToSpec = false
|
|
}
|