package yqlib import ( "testing" ) var expectedWhereIsMyCommentMapKey = `D0, P[], (!!seq)::- p: "" isKey: false hc: "" lc: "" fc: "" - p: hello isKey: true hc: "" lc: hello-world-comment fc: "" - p: hello isKey: false hc: "" lc: "" fc: "" - p: hello.message isKey: true hc: "" lc: "" fc: "" - p: hello.message isKey: false hc: "" lc: "" fc: "" ` var expectedWhereIsMyCommentArray = `D0, P[], (!!seq)::- p: "" isKey: false hc: "" lc: "" fc: "" - p: name isKey: true hc: "" lc: "" fc: "" - p: name isKey: false hc: "" lc: "" fc: "" - p: name.0 isKey: false hc: under-name-comment lc: "" fc: "" ` var commentOperatorScenarios = []expressionScenario{ { description: "Set line comment", subdescription: "Set the comment on the key node for more reliability (see below).", document: `a: cat`, expression: `.a line_comment="single"`, expected: []string{ "D0, P[], (!!map)::a: cat # single\n", }, }, { description: "Set line comment of a maps/arrays", subdescription: "For maps and arrays, you need to set the line comment on the _key_ node. This will also work for scalars.", document: "a:\n b: things", expression: `(.a | key) line_comment="single"`, expected: []string{ "D0, P[], (!!map)::a: # single\n b: things\n", }, }, { skipDoc: true, document: "a: cat\nb: dog", expression: `.a line_comment=.b`, expected: []string{ "D0, P[], (!!map)::a: cat # dog\nb: dog\n", }, }, { skipDoc: true, document: "a: cat\n---\na: dog", expression: `.a line_comment |= documentIndex`, expected: []string{ "D0, P[], (!!map)::a: cat # 0\n", "D1, P[], (!!map)::a: dog # 1\n", }, }, { description: "Use update assign to perform relative updates", document: "a: cat\nb: dog", expression: `.. line_comment |= .`, expected: []string{ "D0, P[], (!!map)::a: cat # cat\nb: dog # dog\n", }, }, { skipDoc: true, document: "a: cat\nb: dog", expression: `.. comments |= .`, expected: []string{ "D0, P[], (!!map)::a: cat # cat\n# cat\n\n# cat\nb: dog # dog\n# dog\n\n# dog\n", }, }, { description: "Where is the comment - map key example", subdescription: "The underlying yaml parser can assign comments in a document to surprising nodes. Use an expression like this to find where you comment is. 'p' indicates the path, 'isKey' is if the node is a map key (as opposed to a map value).\nFrom this, you can see the 'hello-world-comment' is actually on the 'hello' key", document: "hello: # hello-world-comment\n message: world", expression: `[... | {"p": path | join("."), "isKey": is_key, "hc": headComment, "lc": lineComment, "fc": footComment}]`, expected: []string{ expectedWhereIsMyCommentMapKey, }, }, { description: "Retrieve comment - map key example", subdescription: "From the previous example, we know that the comment is on the 'hello' _key_ as a lineComment", document: "hello: # hello-world-comment\n message: world", expression: `.hello | key | line_comment`, expected: []string{ "D0, P[hello], (!!str)::hello-world-comment\n", }, }, { description: "Where is the comment - array example", subdescription: "The underlying yaml parser can assign comments in a document to surprising nodes. Use an expression like this to find where you comment is. 'p' indicates the path, 'isKey' is if the node is a map key (as opposed to a map value).\nFrom this, you can see the 'under-name-comment' is actually on the first child", document: "name:\n # under-name-comment\n - first-array-child", expression: `[... | {"p": path | join("."), "isKey": is_key, "hc": headComment, "lc": lineComment, "fc": footComment}]`, expected: []string{ expectedWhereIsMyCommentArray, }, }, { description: "Retrieve comment - array example", subdescription: "From the previous example, we know that the comment is on the first child as a headComment", document: "name:\n # under-name-comment\n - first-array-child", expression: `.name[0] | headComment`, expected: []string{ "D0, P[name 0], (!!str)::under-name-comment\n", }, }, { description: "Set head comment", document: `a: cat`, expression: `. head_comment="single"`, expected: []string{ "D0, P[], (!!map)::# single\na: cat\n", }, }, { description: "Set head comment of a map entry", document: "f: foo\na:\n b: cat", expression: `(.a | key) head_comment="single"`, expected: []string{ "D0, P[], (!!map)::f: foo\n# single\na:\n b: cat\n", }, }, { description: "Set foot comment, using an expression", document: `a: cat`, expression: `. foot_comment=.a`, expected: []string{ "D0, P[], (!!map)::a: cat\n# cat\n", }, }, { skipDoc: true, description: "Set foot comment, using an expression", document: "a: cat\n\n# hi", expression: `. foot_comment=""`, expected: []string{ "D0, P[], (!!map)::a: cat\n", }, }, { skipDoc: true, document: `a: cat`, expression: `. foot_comment=.b.d`, expected: []string{ "D0, P[], (!!map)::a: cat\n", }, }, { skipDoc: true, document: `a: cat`, expression: `. foot_comment|=.b.d`, expected: []string{ "D0, P[], (!!map)::a: cat\n", }, }, { description: "Remove comment", document: "a: cat # comment\nb: dog # leave this", expression: `.a line_comment=""`, expected: []string{ "D0, P[], (!!map)::a: cat\nb: dog # leave this\n", }, }, { description: "Remove (strip) all comments", subdescription: "Note the use of `...` to ensure key nodes are included.", document: "# hi\n\na: cat # comment\n\n# great\n\nb: # key comment", expression: `... comments=""`, expected: []string{ "D0, P[], (!!map)::a: cat\nb:\n", }, }, { description: "Get line comment", document: "# welcome!\n\na: cat # meow\n\n# have a great day", expression: `.a | line_comment`, expected: []string{ "D0, P[a], (!!str)::meow\n", }, }, { description: "Get head comment", dontFormatInputForDoc: true, document: "# welcome!\n\na: cat # meow\n\n# have a great day", expression: `. | head_comment`, expected: []string{ "D0, P[], (!!str)::welcome!\n\n", }, }, { skipDoc: true, description: "strip trailing comment recurse all", document: "a: cat\n\n# haha", expression: `... comments= ""`, expected: []string{ "D0, P[], (!!map)::a: cat\n", }, }, { skipDoc: true, description: "strip trailing comment recurse values", document: "a: cat\n\n# haha", expression: `.. comments= ""`, expected: []string{ "D0, P[], (!!map)::a: cat\n", }, }, { description: "Head comment with document split", dontFormatInputForDoc: true, document: "# welcome!\n---\n# bob\na: cat # meow\n\n# have a great day", expression: `head_comment`, expected: []string{ "D0, P[], (!!str)::welcome!\nbob\n", }, }, { description: "Get foot comment", dontFormatInputForDoc: true, document: "# welcome!\n\na: cat # meow\n\n# have a great day\n# no really", expression: `. | foot_comment`, expected: []string{ "D0, P[], (!!str)::have a great day\nno really\n", }, }, { description: "leading spaces", skipDoc: true, document: " # hi", expression: `.`, expected: []string{ "D0, P[], (!!null):: # hi\n\n", }, }, { description: "directive", skipDoc: true, document: "%YAML 1.1\n# hi\n", expression: `.`, expected: []string{ "D0, P[], (!!null)::%YAML 1.1\n# hi\n\n", }, }, } func TestCommentOperatorScenarios(t *testing.T) { for _, tt := range commentOperatorScenarios { testScenario(t, &tt) } documentOperatorScenarios(t, "comment-operators", commentOperatorScenarios) }