From 304a74f55d48ad452945ac9a66a15de921772a26 Mon Sep 17 00:00:00 2001 From: Inteon <42113979+inteon@users.noreply.github.com> Date: Tue, 26 Oct 2021 11:10:16 +0200 Subject: [PATCH] improve test framework Signed-off-by: Inteon <42113979+inteon@users.noreply.github.com> --- yaml_test.go | 771 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 462 insertions(+), 309 deletions(-) diff --git a/yaml_test.go b/yaml_test.go index 9da43e1..6827881 100644 --- a/yaml_test.go +++ b/yaml_test.go @@ -13,6 +13,149 @@ import ( yaml "gopkg.in/yaml.v2" ) +/* Test helper functions */ + +func strPtr(str string) *string { + return &str +} + +type errorType int + +const ( + noErrorsType errorType = 0 + fatalErrorsType errorType = 1 << iota +) + +type unmarshalTestCase struct { + encoded []byte + decodeInto interface{} + decoded interface{} + err errorType +} + +type testUnmarshalFunc = func(yamlBytes []byte, obj interface{}) error + +var ( + funcUnmarshal testUnmarshalFunc = func(yamlBytes []byte, obj interface{}) error { + return Unmarshal(yamlBytes, obj) + } + + funcUnmarshalStrict testUnmarshalFunc = func(yamlBytes []byte, obj interface{}) error { + return UnmarshalStrict(yamlBytes, obj) + } +) + +func testUnmarshal(t *testing.T, f testUnmarshalFunc) func(test unmarshalTestCase) error { + return func(test unmarshalTestCase) error { + typ := reflect.TypeOf(test.decodeInto) + if typ.Kind() != reflect.Ptr { + return fmt.Errorf("unmarshalTest.ptr %T is not a pointer type", test.decodeInto) + } + + value := reflect.New(typ.Elem()) + + if !reflect.DeepEqual(test.decodeInto, value.Interface()) { + // There's no reason for ptr to point to non-zero data, + // as we decode into new(right-type), so the data is + // discarded. + // This can easily mean tests that silently don't test + // what they should. To test decoding into existing + // data, see TestPrefilled. + return fmt.Errorf("unmarshalTest.ptr %#v is not a pointer to a zero value", test.decodeInto) + } + + err := f(test.encoded, value.Interface()) + if err != nil && test.err == noErrorsType { + return fmt.Errorf("error unmarshaling YAML: %v", err) + } + if err == nil && test.err&fatalErrorsType != 0 { + return fmt.Errorf("expected a fatal error, but no fatal error was returned, yaml: `%s`", test.encoded) + } + + if test.err&fatalErrorsType != 0 { + // Don't check output if error is fatal + return nil + } + + if !reflect.DeepEqual(value.Elem().Interface(), test.decoded) { + return fmt.Errorf("unmarshal YAML was unsuccessful, expected: %+#v, got: %+#v", test.decoded, value.Elem().Interface()) + } + + return nil + } +} + +type yamlToJSONTestcase struct { + yaml string + json string + // By default we test that reversing the output == input. But if there is a + // difference in the reversed output, you can optionally specify it here. + yaml_reverse_overwrite *string + err errorType +} + +type testYAMLToJSONFunc = func(yamlBytes []byte) ([]byte, error) + +var ( + funcYAMLToJSON testYAMLToJSONFunc = func(yamlBytes []byte) ([]byte, error) { + return YAMLToJSON(yamlBytes) + } + + funcYAMLToJSONStrict testYAMLToJSONFunc = func(yamlBytes []byte) ([]byte, error) { + return YAMLToJSONStrict(yamlBytes) + } +) + +func testYAMLToJSON(t *testing.T, f testYAMLToJSONFunc) func(test yamlToJSONTestcase) error { + return func(test yamlToJSONTestcase) error { + { + // Convert Yaml to Json + genJson, err := f([]byte(test.yaml)) + if err != nil && test.err == noErrorsType { + return fmt.Errorf("Failed to convert YAML to JSON, yaml: `%s`, err: %v", test.yaml, err) + } + if err == nil && test.err&fatalErrorsType != 0 { + return fmt.Errorf("expected a fatal error, but no fatal error was returned, yaml: `%s`", test.yaml) + } + + if test.err&fatalErrorsType != 0 { + // Don't check output if error is fatal + return nil + } + + // Check it against the expected output. + if string(genJson) != test.json { + return fmt.Errorf("Failed to convert YAML to JSON, yaml: `%s`, expected json `%s`, got `%s`", test.yaml, test.json, string(genJson)) + } + } + + { + // Convert JSON to YAML + genYaml, err := JSONToYAML([]byte(test.json)) + if err != nil { + return fmt.Errorf("Failed to convert JSON to YAML, json: `%s`, err: %v", test.json, err) + } + + // Set the string that we will compare the reversed output to. + yaml := test.yaml + + // If a special reverse string was specified, use that instead. + if test.yaml_reverse_overwrite != nil { + yaml = *test.yaml_reverse_overwrite + } + + // Check the reverse is equal to the input (or to *c.reverse). + if string(genYaml) != yaml { + return fmt.Errorf("Failed to convert JSON to YAML, json: `%s`, expected yaml `%s`, got `%s`", test.json, yaml, string(genYaml)) + } + } + + return nil + } +} + +/* Start tests */ + type MarshalTest struct { A string B int64 @@ -63,186 +206,201 @@ type NestedSlice struct { C *string } -func TestUnmarshal(t *testing.T) { - y := []byte("a: 1") - s1 := UnmarshalString{} - e1 := UnmarshalString{A: "1"} - unmarshal(t, y, &s1, &e1) - - y = []byte("a: true") - s1 = UnmarshalString{} - e1 = UnmarshalString{A: "true"} - unmarshal(t, y, &s1, &e1) - - y = []byte("true: 1") - s1 = UnmarshalString{} - e1 = UnmarshalString{True: "1"} - unmarshal(t, y, &s1, &e1) - - y = []byte("a:\n a: 1") - s2 := UnmarshalNestedString{} - e2 := UnmarshalNestedString{NestedString{"1"}} - unmarshal(t, y, &s2, &e2) - - y = []byte("a:\n - b: abc\n c: def\n - b: 123\n c: 456\n") - s3 := UnmarshalSlice{} - e3 := UnmarshalSlice{[]NestedSlice{NestedSlice{"abc", strPtr("def")}, NestedSlice{"123", strPtr("456")}}} - unmarshal(t, y, &s3, &e3) - - y = []byte("a:\n b: 1") - s4 := UnmarshalStringMap{} - e4 := UnmarshalStringMap{map[string]string{"b": "1"}} - unmarshal(t, y, &s4, &e4) - - y = []byte(` -a: - name: TestA -b: - name: TestB -`) - type NamedThing struct { - Name string `json:"name"` - } - s5 := map[string]*NamedThing{} - e5 := map[string]*NamedThing{ - "a": &NamedThing{Name: "TestA"}, - "b": &NamedThing{Name: "TestB"}, - } - unmarshal(t, y, &s5, &e5) +type NamedThing struct { + Name string `json:"name"` } -func unmarshal(t *testing.T, y []byte, s, e interface{}, opts ...JSONOpt) { - err := Unmarshal(y, s, opts...) - if err != nil { - t.Errorf("error unmarshaling YAML: %v", err) +type NamedThing2 struct { + Name string `json:"name"` + ID string `json:"id"` +} + +func TestUnmarshal(t *testing.T) { + tester := testUnmarshal(t, funcUnmarshal) + + if err := tester(unmarshalTestCase{ + encoded: []byte("A: 1"), + decodeInto: new(UnmarshalString), + decoded: UnmarshalString{A: "1"}, + }); err != nil { + t.Error(err) } - if !reflect.DeepEqual(s, e) { - t.Errorf("unmarshal YAML was unsuccessful, expected: %+#v, got: %+#v", - e, s) + if err := tester(unmarshalTestCase{ + encoded: []byte("a: true"), + decodeInto: new(UnmarshalString), + decoded: UnmarshalString{A: "true"}, + }); err != nil { + t.Error(err) } -} -func TestUnmarshalStrict(t *testing.T) { - y := []byte("a: 1") - s1 := UnmarshalString{} - e1 := UnmarshalString{A: "1"} - unmarshalStrict(t, y, &s1, &e1) - - y = []byte("a: true") - s1 = UnmarshalString{} - e1 = UnmarshalString{A: "true"} - unmarshalStrict(t, y, &s1, &e1) - - y = []byte("true: 1") - s1 = UnmarshalString{} - e1 = UnmarshalString{True: "1"} - unmarshalStrict(t, y, &s1, &e1) - - y = []byte("a:\n a: 1") - s2 := UnmarshalNestedString{} - e2 := UnmarshalNestedString{NestedString{"1"}} - unmarshalStrict(t, y, &s2, &e2) - - y = []byte("a:\n - b: abc\n c: def\n - b: 123\n c: 456\n") - s3 := UnmarshalSlice{} - e3 := UnmarshalSlice{[]NestedSlice{NestedSlice{"abc", strPtr("def")}, NestedSlice{"123", strPtr("456")}}} - unmarshalStrict(t, y, &s3, &e3) - - y = []byte("a:\n b: 1") - s4 := UnmarshalStringMap{} - e4 := UnmarshalStringMap{map[string]string{"b": "1"}} - unmarshalStrict(t, y, &s4, &e4) - - y = []byte(` -a: - name: TestA -b: - name: TestB -`) - type NamedThing struct { - Name string `json:"name"` - } - s5 := map[string]*NamedThing{} - e5 := map[string]*NamedThing{ - "a": &NamedThing{Name: "TestA"}, - "b": &NamedThing{Name: "TestB"}, - } - unmarshal(t, y, &s5, &e5) + if err := tester(unmarshalTestCase{ + encoded: []byte("true: 1"), + decodeInto: new(UnmarshalString), + decoded: UnmarshalString{True: "1"}, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n a: 1"), + decodeInto: new(UnmarshalNestedString), + decoded: UnmarshalNestedString{NestedString{"1"}}, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n - b: abc\n c: def\n - b: 123\n c: 456"), + decodeInto: new(UnmarshalSlice), + decoded: UnmarshalSlice{[]NestedSlice{{"abc", strPtr("def")}, {"123", strPtr("456")}}}, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n b: 1"), + decodeInto: new(UnmarshalStringMap), + decoded: UnmarshalStringMap{map[string]string{"b": "1"}}, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n b: 1"), + decodeInto: new(UnmarshalStringMap), + decoded: UnmarshalStringMap{map[string]string{"b": "1"}}, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n name: TestA\nb:\n name: TestB"), + decodeInto: new(map[string]*NamedThing), + decoded: map[string]*NamedThing{ + "a": {Name: "TestA"}, + "b": {Name: "TestB"}, + }, + }); err != nil { + t.Error(err) + } // When using not-so-strict unmarshal, we should // be picking up the ID-1 as the value in the "id" field - y = []byte(` -a: - name: TestA - id: ID-A - id: ID-1 -`) - type NamedThing2 struct { - Name string `json:"name"` - ID string `json:"id"` - } - s6 := map[string]*NamedThing2{} - e6 := map[string]*NamedThing2{ - "a": {Name: "TestA", ID: "ID-1"}, - } - unmarshal(t, y, &s6, &e6) + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n name: TestA\n id: ID-A\n id: ID-1"), + decodeInto: new(map[string]*NamedThing2), + decoded: map[string]*NamedThing2{ + "a": {Name: "TestA", ID: "ID-1"}, + }, + }); err != nil { + t.Error(err) + } } -func TestUnmarshalStrictFails(t *testing.T) { - y := []byte("a: true\na: false") - s1 := UnmarshalString{} - unmarshalStrictFail(t, y, &s1) - - y = []byte("a:\n - b: abc\n c: 32\n b: 123") - s2 := UnmarshalSlice{} - unmarshalStrictFail(t, y, &s2) - - y = []byte("a:\n b: 1\n c: 3") - s3 := UnmarshalStringMap{} - unmarshalStrictFail(t, y, &s3) - - type NamedThing struct { - Name string `json:"name"` - ID string `json:"id"` - } - // When using strict unmarshal, we should see - // the unmarshal fail if there are multiple keys - y = []byte(` -a: - name: TestA - id: ID-A - id: ID-1 -`) - s4 := NamedThing{} - unmarshalStrictFail(t, y, &s4) - - // Strict unmarshal should fail for unknown fields - y = []byte(` -name: TestB -id: ID-B -unknown: Some-Value -`) - s5 := NamedThing{} - unmarshalStrictFail(t, y, &s5) -} +func TestUnmarshalStrict(t *testing.T) { + tester := testUnmarshal(t, funcUnmarshalStrict) + + if err := tester(unmarshalTestCase{ + encoded: []byte("a: 1"), + decodeInto: new(UnmarshalString), + decoded: UnmarshalString{A: "1"}, + }); err != nil { + t.Error(err) + } -func unmarshalStrict(t *testing.T, y []byte, s, e interface{}, opts ...JSONOpt) { - err := UnmarshalStrict(y, s, opts...) - if err != nil { - t.Errorf("error unmarshaling YAML: %v", err) + if err := tester(unmarshalTestCase{ + encoded: []byte("a: true"), + decodeInto: new(UnmarshalString), + decoded: UnmarshalString{A: "true"}, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("true: 1"), + decodeInto: new(UnmarshalString), + decoded: UnmarshalString{True: "1"}, + }); err != nil { + t.Error(err) } - if !reflect.DeepEqual(s, e) { - t.Errorf("unmarshal YAML was unsuccessful, expected: %+#v, got: %+#v", - e, s) + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n a: 1"), + decodeInto: new(UnmarshalNestedString), + decoded: UnmarshalNestedString{NestedString{"1"}}, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n - b: abc\n c: def\n - b: 123\n c: 456"), + decodeInto: new(UnmarshalSlice), + decoded: UnmarshalSlice{[]NestedSlice{{"abc", strPtr("def")}, {"123", strPtr("456")}}}, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n b: 1"), + decodeInto: new(UnmarshalStringMap), + decoded: UnmarshalStringMap{map[string]string{"b": "1"}}, + }); err != nil { + t.Error(err) + } + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n name: TestA\nb:\n name: TestB"), + decodeInto: new(map[string]*NamedThing), + decoded: map[string]*NamedThing{ + "a": {Name: "TestA"}, + "b": {Name: "TestB"}, + }, + }); err != nil { + t.Error(err) } } -func unmarshalStrictFail(t *testing.T, y []byte, s interface{}, opts ...JSONOpt) { - err := UnmarshalStrict(y, s, opts...) - if err == nil { - t.Errorf("error unmarshaling YAML: %v", err) +func TestUnmarshalStrictFails(t *testing.T) { + tester := testUnmarshal(t, funcUnmarshalStrict) + + if err := tester(unmarshalTestCase{ + encoded: []byte("a: true\na: false"), + decodeInto: new(UnmarshalString), + err: fatalErrorsType, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n - b: abc\n c: 32\n b: 123"), + decodeInto: new(UnmarshalSlice), + err: fatalErrorsType, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n b: 1\n c: 3"), + decodeInto: new(UnmarshalStringMap), + err: fatalErrorsType, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("a:\n name: TestA\n id: ID-A\n id: ID-1"), + decodeInto: new(NamedThing2), + err: fatalErrorsType, + }); err != nil { + t.Error(err) + } + + if err := tester(unmarshalTestCase{ + encoded: []byte("name: TestB\nid: ID-B\nunknown: Some-Value"), + decodeInto: new(NamedThing2), + err: fatalErrorsType, + }); err != nil { + t.Error(err) } } @@ -262,172 +420,167 @@ const ( ) func TestJSONToYAML(t *testing.T) { - cases := []Case{ - { - `{"t":"a"}`, - "t: a\n", - nil, - }, { - `{"t":null}`, - "t: null\n", - nil, - }, { - `{"t":"this is very long line with spaces and it must be longer than 80 so we will repeat that it must be longer that 80"}`, - "t: this is very long line with spaces and it must be longer than 80 so we will repeat\n that it must be longer that 80\n", - nil, - }, + tester := testYAMLToJSON(t, funcYAMLToJSON) + + if err := tester(yamlToJSONTestcase{ + yaml: "t: a\n", + json: `{"t":"a"}`, + }); err != nil { + t.Error(err) } - runCases(t, RunTypeJSONToYAML, cases) + if err := tester(yamlToJSONTestcase{ + yaml: "t: null\n", + json: `{"t":null}`, + }); err != nil { + t.Error(err) + } + + if err := tester(yamlToJSONTestcase{ + yaml: "t: this is very long line with spaces and it must be longer than 80 so we will repeat\n that it must be longer that 80\n", + json: `{"t":"this is very long line with spaces and it must be longer than 80 so we will repeat that it must be longer that 80"}`, + }); err != nil { + t.Error(err) + } } func TestYAMLToJSON(t *testing.T) { - cases := []Case{ - { - "t: a\n", - `{"t":"a"}`, - nil, - }, { - "t: \n", - `{"t":null}`, - strPtr("t: null\n"), - }, { - "t: null\n", - `{"t":null}`, - nil, - }, { - "1: a\n", - `{"1":"a"}`, - strPtr("\"1\": a\n"), - }, { - "1000000000000000000000000000000000000: a\n", - `{"1e+36":"a"}`, - strPtr("\"1e+36\": a\n"), - }, { - "1e+36: a\n", - `{"1e+36":"a"}`, - strPtr("\"1e+36\": a\n"), - }, { - "\"1e+36\": a\n", - `{"1e+36":"a"}`, - nil, - }, { - "\"1.2\": a\n", - `{"1.2":"a"}`, - nil, - }, { - "- t: a\n", - `[{"t":"a"}]`, - nil, - }, { - "- t: a\n" + - "- t:\n" + - " b: 1\n" + - " c: 2\n", - `[{"t":"a"},{"t":{"b":1,"c":2}}]`, - nil, - }, { - `[{t: a}, {t: {b: 1, c: 2}}]`, - `[{"t":"a"},{"t":{"b":1,"c":2}}]`, - strPtr("- t: a\n" + - "- t:\n" + - " b: 1\n" + - " c: 2\n"), - }, { - "- t: \n", - `[{"t":null}]`, - strPtr("- t: null\n"), - }, { - "- t: null\n", - `[{"t":null}]`, - nil, - }, + tester := testYAMLToJSON(t, funcYAMLToJSON) + + if err := tester(yamlToJSONTestcase{ + yaml: "t: a\n", + json: `{"t":"a"}`, + }); err != nil { + t.Error(err) } - // Cases that should produce errors. - _ = []Case{ - { - "~: a", - `{"null":"a"}`, - nil, - }, { - "a: !!binary gIGC\n", - "{\"a\":\"\x80\x81\x82\"}", - nil, - }, + if err := tester(yamlToJSONTestcase{ + yaml: "t: ", + json: `{"t":null}`, + yaml_reverse_overwrite: strPtr("t: null\n"), + }); err != nil { + t.Error(err) } - runCases(t, RunTypeYAMLToJSON, cases) -} + if err := tester(yamlToJSONTestcase{ + yaml: "t: null\n", + json: `{"t":null}`, + }); err != nil { + t.Error(err) + } -func runCases(t *testing.T, runType RunType, cases []Case) { - var f func([]byte) ([]byte, error) - var invF func([]byte) ([]byte, error) - var msg string - var invMsg string - if runType == RunTypeJSONToYAML { - f = JSONToYAML - invF = YAMLToJSON - msg = "JSON to YAML" - invMsg = "YAML back to JSON" - } else { - f = YAMLToJSON - invF = JSONToYAML - msg = "YAML to JSON" - invMsg = "JSON back to YAML" - } - - for _, c := range cases { - // Convert the string. - t.Logf("converting %s\n", c.input) - output, err := f([]byte(c.input)) - if err != nil { - t.Errorf("Failed to convert %s, input: `%s`, err: %v", msg, c.input, err) - } + if err := tester(yamlToJSONTestcase{ + yaml: "1: a", + json: `{"1":"a"}`, + yaml_reverse_overwrite: strPtr("\"1\": a\n"), + }); err != nil { + t.Error(err) + } - // Check it against the expected output. - if string(output) != c.output { - t.Errorf("Failed to convert %s, input: `%s`, expected `%s`, got `%s`", - msg, c.input, c.output, string(output)) - } + if err := tester(yamlToJSONTestcase{ + yaml: "1000000000000000000000000000000000000: a", + json: `{"1e+36":"a"}`, + yaml_reverse_overwrite: strPtr("\"1e+36\": a\n"), + }); err != nil { + t.Error(err) + } - // Set the string that we will compare the reversed output to. - reverse := c.input - // If a special reverse string was specified, use that instead. - if c.reverse != nil { - reverse = *c.reverse - } + if err := tester(yamlToJSONTestcase{ + yaml: "1e+36: a", + json: `{"1e+36":"a"}`, + yaml_reverse_overwrite: strPtr("\"1e+36\": a\n"), + }); err != nil { + t.Error(err) + } - // Reverse the output. - input, err := invF(output) - if err != nil { - t.Errorf("Failed to convert %s, input: `%s`, err: %v", invMsg, string(output), err) - } + if err := tester(yamlToJSONTestcase{ + yaml: "\"1e+36\": a\n", + json: `{"1e+36":"a"}`, + }); err != nil { + t.Error(err) + } - // Check the reverse is equal to the input (or to *c.reverse). - if string(input) != reverse { - t.Errorf("Failed to convert %s, input: `%s`, expected `%s`, got `%s`", - invMsg, string(output), reverse, string(input)) - } + if err := tester(yamlToJSONTestcase{ + yaml: "\"1.2\": a\n", + json: `{"1.2":"a"}`, + }); err != nil { + t.Error(err) } -} + if err := tester(yamlToJSONTestcase{ + yaml: "- t: a\n", + json: `[{"t":"a"}]`, + }); err != nil { + t.Error(err) + } + + if err := tester(yamlToJSONTestcase{ + yaml: "- t: a\n- t:\n b: 1\n c: 2\n", + json: `[{"t":"a"},{"t":{"b":1,"c":2}}]`, + }); err != nil { + t.Error(err) + } + + if err := tester(yamlToJSONTestcase{ + yaml: `[{t: a}, {t: {b: 1, c: 2}}]`, + json: `[{"t":"a"},{"t":{"b":1,"c":2}}]`, + yaml_reverse_overwrite: strPtr("- t: a\n- t:\n b: 1\n c: 2\n"), + }); err != nil { + t.Error(err) + } + + if err := tester(yamlToJSONTestcase{ + yaml: "- t: ", + json: `[{"t":null}]`, + yaml_reverse_overwrite: strPtr("- t: null\n"), + }); err != nil { + t.Error(err) + } + + if err := tester(yamlToJSONTestcase{ + yaml: "- t: null\n", + json: `[{"t":null}]`, + }); err != nil { + t.Error(err) + } + + // expect YAMLtoJSON to pass on duplicate field names + if err := tester(yamlToJSONTestcase{ + yaml: "foo: bar\nfoo: baz\n", + json: `{"foo":"baz"}`, + yaml_reverse_overwrite: strPtr("foo: baz\n"), + }); err != nil { + t.Error(err) + } -// To be able to easily fill in the *Case.reverse string above. -func strPtr(s string) *string { - return &s + // Cases that should produce errors. + if err := tester(yamlToJSONTestcase{ + yaml: "~: a", + json: `{"null":"a"}`, + err: fatalErrorsType, + }); err != nil { + t.Error(err) + } + + if err := tester(yamlToJSONTestcase{ + yaml: "a: !!binary gIGC", + json: `{"a":"\ufffd\ufffd\ufffd"}`, + yaml_reverse_overwrite: strPtr("a: \ufffd\ufffd\ufffd\n"), + }); err != nil { + t.Error(err) + } } func TestYAMLToJSONStrict(t *testing.T) { - const data = ` -foo: bar -foo: baz -` - if _, err := YAMLToJSON([]byte(data)); err != nil { - t.Error("expected YAMLtoJSON to pass on duplicate field names") - } - if _, err := YAMLToJSONStrict([]byte(data)); err == nil { - t.Error("expected YAMLtoJSONStrict to fail on duplicate field names") + tester := testYAMLToJSON(t, funcYAMLToJSONStrict) + + // expect YAMLtoJSONStrict to fail on duplicate field names + if err := tester(yamlToJSONTestcase{ + yaml: "foo: bar\nfoo: baz", + json: `[{"foo":"baz"}]`, + err: fatalErrorsType, + }); err != nil { + t.Error(err) } }