From 921b00626545b5d9a109baea51fc20744c10b404 Mon Sep 17 00:00:00 2001 From: Martin Sucha Date: Mon, 13 Mar 2023 11:42:33 +0100 Subject: [PATCH 1/2] Don't trim all space characters in SequenceNode.blockStyleString This fixes https://github.com/goccy/go-yaml/issues/356. The code would have removed more spaces than it added. A better solution long-term would probably be to add a specialized method to StringNode to not add the prefix in the first place. --- ast/ast.go | 3 ++- encode_test.go | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ast/ast.go b/ast/ast.go index 0e3462e4..f535a246 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -1570,8 +1570,9 @@ func (n *SequenceNode) blockStyleString() string { diffLength := len(splittedValues[0]) - len(trimmedFirstValue) if len(splittedValues) > 1 && value.Type() == StringType || value.Type() == LiteralType { // If multi-line string, the space characters for indent have already been added, so delete them. + prefix := space + " " for i := 1; i < len(splittedValues); i++ { - splittedValues[i] = strings.TrimLeft(splittedValues[i], " ") + splittedValues[i] = strings.TrimPrefix(splittedValues[i], prefix) } } newValues := []string{trimmedFirstValue} diff --git a/encode_test.go b/encode_test.go index db360281..d97f727c 100644 --- a/encode_test.go +++ b/encode_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "github.com/goccy/go-yaml/parser" "math" "reflect" "strconv" @@ -1399,6 +1400,24 @@ func Example_MarshalYAML() { // field: 13 } +func TestIssue356(t *testing.T) { + in := `args: + - | + key: + nest1: something + nest2: + nest2a: b +` + f, err := parser.ParseBytes([]byte(in), 0) + if err != nil { + t.Fatalf("parse: %v", err) + } + got := f.String() + if in != got { + t.Fatalf("failed to encode.\nexpected:\n%s\nbut got:\n%s\n", in, got) + } +} + func TestMarshalIndentWithMultipleText(t *testing.T) { t.Run("depth1", func(t *testing.T) { b, err := yaml.MarshalWithOptions(map[string]interface{}{ From e9e4b8dca9c14a91efe65938331210104322cb5e Mon Sep 17 00:00:00 2001 From: Martin Sucha Date: Tue, 21 Mar 2023 10:23:35 +0100 Subject: [PATCH 2/2] Add issue 356 test case for block with first empty line The indentation level in a block scalar is determined by the first non-empty line. --- encode_test.go | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/encode_test.go b/encode_test.go index d97f727c..146abb0f 100644 --- a/encode_test.go +++ b/encode_test.go @@ -1401,20 +1401,42 @@ func Example_MarshalYAML() { } func TestIssue356(t *testing.T) { - in := `args: + tests := map[string]struct { + in string + }{ + "content on first line": { + in: `args: - | + key: nest1: something nest2: nest2a: b -` - f, err := parser.ParseBytes([]byte(in), 0) - if err != nil { - t.Fatalf("parse: %v", err) +`, + }, + "empty first line": { + in: `args: + - | + + key: + nest1: something + nest2: + nest2a: b +`, + }, } - got := f.String() - if in != got { - t.Fatalf("failed to encode.\nexpected:\n%s\nbut got:\n%s\n", in, got) + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + f, err := parser.ParseBytes([]byte(test.in), 0) + if err != nil { + t.Fatalf("parse: %v", err) + } + got := f.String() + if test.in != got { + t.Fatalf("failed to encode.\nexpected:\n%s\nbut got:\n%s\n", test.in, got) + } + }) } }