-
-
Notifications
You must be signed in to change notification settings - Fork 197
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Below is some test cases I'm using to pinpoint an issue I'm seeing when using BytesUnmarshaler
.
It seems like the main problem happens when there are yaml anchors?
I was actually trying to reproduce another issue (but still w/ BytesUnmarshaler
) that cropped up while using anchors that actually causes the parsed yaml to produce an error when reparsing (from *ast.File.String()
)
In the test cases here the parsed yaml produced by *ast.File.String()
is not invalid yaml so there is no error however the data is incorrect.
Running the below tests:
$ go test . ─╯
--- FAIL: TestComplexWithBytesUnmarshaler (0.00s)
main_test.go:56: expected 2, got 0
FAIL
FAIL test 0.211s
FAIL
Test cases
package main
import (
"fmt"
"testing"
"github.com/goccy/go-yaml"
"github.com/goccy/go-yaml/parser"
)
var complexTestData = []byte(`
x-foo: &data
bar:
- one
- two
foo:
stuff: *data
`)
var simpleTestData = []byte(`
foo:
- one
- two
`)
func (t *ComplexWithBytesUnmarshaler) UnmarshalYAML(dt []byte) error {
type intermediate ComplexWithBytesUnmarshaler
var i intermediate
if err := unmarshal(&i, dt); err != nil {
return err
}
*t = ComplexWithBytesUnmarshaler(i)
return nil
}
func unmarshal[T any](target *T, dt []byte) error {
parsed, err := parser.ParseBytes(dt, 0)
if err != nil {
return fmt.Errorf("error parsing: %w", err)
}
return yaml.NewDecoder(parsed).Decode(target)
}
func TestComplexWithBytesUnmarshaler(t *testing.T) {
var c ComplexWithBytesUnmarshaler
if err := yaml.Unmarshal(complexTestData, &c); err != nil {
t.Fatalf("error unmarshalling: %v", err)
}
if len(c.Foo.Stuff.Bar) != 2 {
t.Fatalf("expected 2, got %d", len(c.Foo.Stuff.Bar))
}
if c.Foo.Stuff.Bar[0] != "one" {
t.Fatalf("expected one, got %s", c.Foo.Stuff.Bar[0])
}
if c.Foo.Stuff.Bar[1] != "two" {
t.Fatalf("expected two, got %s", c.Foo.Stuff.Bar[1])
}
}
func checkSliceData(t *testing.T, dt []string) {
t.Helper()
if len(dt) != 2 {
t.Fatalf("expected 2, got %d", len(dt))
}
if dt[0] != "one" {
t.Fatalf("expected one, got %s", dt[0])
}
if dt[1] != "two" {
t.Fatalf("expected two, got %s", dt[1])
}
}
func TestComplexNoCustomUnmarshaller(t *testing.T) {
var c ComplexNoCustomUnmarshaller
if err := yaml.Unmarshal(complexTestData, &c); err != nil {
t.Fatalf("error unmarshalling: %v", err)
}
checkSliceData(t, c.Foo.Stuff.Bar)
// check again with the custom marshal implementation
c = ComplexNoCustomUnmarshaller{}
if err := unmarshal(&c, complexTestData); err != nil {
t.Fatalf("error unmarshalling: %v", err)
}
checkSliceData(t, c.Foo.Stuff.Bar)
t.Run("with intermediate type", func(t *testing.T) {
type intermediate ComplexNoCustomUnmarshaller
var i intermediate
if err := unmarshal(&i, complexTestData); err != nil {
t.Fatal(err)
}
c2 := &ComplexNoCustomUnmarshaller{}
*c2 = ComplexNoCustomUnmarshaller(i)
checkSliceData(t, c2.Foo.Stuff.Bar)
})
}
func TestSimpleWithBytesUnmarshaler(t *testing.T) {
var s SimpleWithBytesUnmarshaler
if err := yaml.Unmarshal(simpleTestData, &s); err != nil {
t.Fatalf("error unmarshalling: %v", err)
}
checkSliceData(t, s.Foo)
}
func TestSimpleNoCustomUnmarshaller(t *testing.T) {
var s SimpleNoCustomUnmarshaller
if err := unmarshal(&s, simpleTestData); err != nil {
t.Fatalf("error unmarshalling: %v", err)
}
checkSliceData(t, s.Foo)
// check again with the custom marshal implementation
s = SimpleNoCustomUnmarshaller{}
if err := unmarshal(&s, simpleTestData); err != nil {
t.Fatalf("error unmarshalling: %v", err)
}
checkSliceData(t, s.Foo)
t.Run("with intermediate type", func(t *testing.T) {
type intermediate SimpleNoCustomUnmarshaller
var i intermediate
if err := unmarshal(&i, simpleTestData); err != nil {
t.Fatal(err)
}
s := &SimpleNoCustomUnmarshaller{}
*s = SimpleNoCustomUnmarshaller(i)
checkSliceData(t, s.Foo)
})
}
type SimpleWithBytesUnmarshaler struct {
Foo []string `yaml:"foo"`
}
type SimpleNoCustomUnmarshaller struct {
Foo []string `yaml:"foo"`
}
type ComplexWithBytesUnmarshaler struct {
Foo struct {
Stuff struct {
Bar []string `yaml:"bar"`
} `yaml:"stuff"`
} `yaml:"foo"`
}
type ComplexNoCustomUnmarshaller struct {
Foo struct {
Stuff struct {
Bar []string `yaml:"bar"`
} `yaml:"stuff"`
} `yaml:"foo"`
}
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working