mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-06 03:13:48 +02:00
8d6ef40020
* chore(yaml): upgraded from yaml.v2 to yaml.v3 * provided internal package to take care of backward compatible settings: * UnmarshalStrict method * mute io.EOF unmarshaling errors * marshal indenting with 2 chars * adapted unit tests to new yaml v3 Signed-off-by: Frederic BIDON <fredbi@yahoo.com> * fixed failing tests Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
265 lines
5.5 KiB
Go
265 lines
5.5 KiB
Go
package yaml
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestYAMLMarshalError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type yamlMarshalError struct {
|
|
BoolValue bool `yaml:"bool_value"`
|
|
FuncValue func() `yaml:"func_value"`
|
|
}
|
|
|
|
v := yamlMarshalError{
|
|
BoolValue: true,
|
|
FuncValue: func() {},
|
|
}
|
|
|
|
require.Panics(t, func() {
|
|
_, _ = Marshal(v)
|
|
})
|
|
}
|
|
|
|
func TestYAML(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type (
|
|
yamlKey struct {
|
|
BoolValue bool `yaml:"bool_value"`
|
|
NumberValue float64 `yaml:"number_value"`
|
|
StringValue string `yaml:"string_value"`
|
|
}
|
|
yamlObject struct {
|
|
Array []string `yaml:"array"`
|
|
Key yamlKey `yaml:"key"`
|
|
}
|
|
yamlReceiver struct {
|
|
Object yamlObject `yaml:"object"`
|
|
}
|
|
|
|
interfaceOrObject struct {
|
|
obj yamlReceiver
|
|
iface interface{}
|
|
}
|
|
)
|
|
|
|
for _, toPin := range []struct {
|
|
Title string
|
|
InputYAML []byte
|
|
ExpectedYAML []byte // optional: when marshaled YAML is expected to differ from raw input (e.g. on bool flags)
|
|
Expected interfaceOrObject // maybe either untyped interface{} or yamlObject struct with struct tags
|
|
ExpectError bool
|
|
WantsStrict bool // apply Strict mode
|
|
}{
|
|
{
|
|
Title: "happy path, untyped",
|
|
InputYAML: testYAMLObject(),
|
|
Expected: interfaceOrObject{
|
|
iface: map[string]interface{}{
|
|
"object": map[string]interface{}{
|
|
"key": map[string]interface{}{
|
|
"string_value": "This is a doc.\nOn multiple lines.\n",
|
|
"bool_value": "y",
|
|
"number_value": 10.23,
|
|
},
|
|
"array": []interface{}{"x", "y"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Title: "happy path strict, untyped",
|
|
InputYAML: testYAMLObject(),
|
|
WantsStrict: true,
|
|
Expected: interfaceOrObject{
|
|
iface: map[string]interface{}{
|
|
"object": map[string]interface{}{
|
|
"key": map[string]interface{}{
|
|
"string_value": "This is a doc.\nOn multiple lines.\n",
|
|
"bool_value": "y",
|
|
"number_value": 10.23,
|
|
},
|
|
"array": []interface{}{"x", "y"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Title: "happy path strict, explicit target",
|
|
InputYAML: testYAMLObject(),
|
|
ExpectedYAML: testYAMLObjectBool(),
|
|
WantsStrict: true,
|
|
Expected: interfaceOrObject{
|
|
iface: nil,
|
|
obj: yamlReceiver{
|
|
Object: yamlObject{
|
|
Key: yamlKey{
|
|
StringValue: "This is a doc.\nOn multiple lines.\n",
|
|
BoolValue: true,
|
|
NumberValue: 10.23,
|
|
},
|
|
Array: []string{"x", "y"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Title: "happy path non-strict, explicit target",
|
|
InputYAML: testYAMLObjectNonStrict(),
|
|
ExpectedYAML: testYAMLObjectBool(),
|
|
WantsStrict: false,
|
|
Expected: interfaceOrObject{
|
|
iface: nil,
|
|
obj: yamlReceiver{
|
|
Object: yamlObject{
|
|
Key: yamlKey{
|
|
StringValue: "This is a doc.\nOn multiple lines.\n",
|
|
BoolValue: true,
|
|
NumberValue: 10.23,
|
|
},
|
|
Array: []string{"x", "y"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Title: "happy path strict, explicit target: unknown field failure",
|
|
InputYAML: testYAMLObjectNonStrict(),
|
|
ExpectedYAML: testYAMLObjectBool(),
|
|
WantsStrict: true,
|
|
ExpectError: true,
|
|
Expected: interfaceOrObject{
|
|
iface: nil,
|
|
obj: yamlReceiver{
|
|
Object: yamlObject{
|
|
Key: yamlKey{
|
|
StringValue: "This is a doc.\nOn multiple lines.\n",
|
|
BoolValue: true,
|
|
NumberValue: 10.23,
|
|
},
|
|
Array: []string{"x", "y"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
} {
|
|
testCase := toPin
|
|
|
|
t.Run(testCase.Title, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var (
|
|
err error
|
|
b, expectedOutput []byte
|
|
)
|
|
iface := testCase.Expected.iface
|
|
obj := testCase.Expected.obj
|
|
|
|
expectedInput := toPlainYaml(testCase.InputYAML)
|
|
|
|
if testCase.WantsStrict {
|
|
if iface != nil {
|
|
err = UnmarshalStrict(expectedInput, &iface)
|
|
} else {
|
|
err = UnmarshalStrict(expectedInput, &obj)
|
|
}
|
|
} else {
|
|
if iface != nil {
|
|
err = Unmarshal(expectedInput, &iface)
|
|
} else {
|
|
err = Unmarshal(expectedInput, &obj)
|
|
}
|
|
}
|
|
|
|
if testCase.ExpectError {
|
|
require.Error(t, err)
|
|
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
|
|
if iface != nil {
|
|
require.EqualValues(t, testCase.Expected.iface, iface)
|
|
|
|
b, err = Marshal(iface)
|
|
require.NoError(t, err)
|
|
} else {
|
|
require.EqualValues(t, testCase.Expected.obj, obj)
|
|
|
|
b, err = Marshal(obj)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
if testCase.ExpectedYAML == nil {
|
|
expectedOutput = expectedInput
|
|
} else {
|
|
expectedOutput = toPlainYaml(testCase.ExpectedYAML)
|
|
}
|
|
|
|
require.EqualValues(t, expectedOutput, b)
|
|
})
|
|
}
|
|
}
|
|
|
|
func toPlainYaml(in []byte) []byte {
|
|
// ensure we got legit yaml for go strings that may have been reindented using tabs, or leading new CR in source.
|
|
return bytes.ReplaceAll(
|
|
bytes.TrimLeft(in, "\n\r"),
|
|
[]byte("\t"), bytes.Repeat([]byte(" "), 4),
|
|
)
|
|
}
|
|
|
|
func testYAMLObject() []byte {
|
|
return []byte(`
|
|
object:
|
|
array:
|
|
- x
|
|
- "y"
|
|
key:
|
|
bool_value: "y"
|
|
number_value: 10.23
|
|
string_value: |
|
|
This is a doc.
|
|
On multiple lines.
|
|
`)
|
|
}
|
|
|
|
func testYAMLObjectBool() []byte {
|
|
// same object, but the "y" YAML for bool has been marshaled as "true"
|
|
return []byte(`
|
|
object:
|
|
array:
|
|
- x
|
|
- "y"
|
|
key:
|
|
bool_value: true
|
|
number_value: 10.23
|
|
string_value: |
|
|
This is a doc.
|
|
On multiple lines.
|
|
`)
|
|
}
|
|
|
|
func testYAMLObjectNonStrict() []byte {
|
|
// same object, but with an extra unknown value
|
|
return []byte(`
|
|
object:
|
|
array:
|
|
- x
|
|
- "y"
|
|
key:
|
|
bool_value: true
|
|
number_value: 10.23
|
|
string_value: |
|
|
This is a doc.
|
|
On multiple lines.
|
|
unknown: 'wrong'
|
|
`)
|
|
}
|