json2go/json2go_test.go(view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
package json2go
import (
"errors"
"fmt"
"reflect"
"strings"
"testing"
)
func field(name, type_ string, json_ ...string) string {
if strings.Contains(type_, "struct") {
return fmt.Sprintf("\n%s %s", name, type_)
}
tag := strings.ToLower(name)
if len(json_) == 1 {
tag = json_[0]
}
return fmt.Sprintf("\n%s %s `json:\"%s\"`", name, type_, tag)
}
func TestTransformer_Transform(t *testing.T) {
tests := map[string]struct {
input string
output string
err error
}{
"simple object": {
input: `{"name": "Olex", "active": true, "age": 420}`,
output: "type Out struct {" +
field("Active", "bool") +
field("Age", "int") +
field("Name", "string") +
"\n}",
},
"invalid json": {
err: ErrInvalidJSON,
input: `{"invalid":json}`,
},
"snake_case to CamelCase": {
input: `{"first_name": "Bob", "last_name": "Bobberson"}`,
output: "type Out struct {" +
field("FirstName", "string", "first_name") +
field("LastName", "string", "last_name") +
"\n}",
},
"nested object and array": {
input: `{"user": {"name": "Alice", "score": 95.5}, "tags": ["go", "json"]}`,
output: "type Out struct {" +
field("Tags", "[]string") +
field("User", "struct {") +
field("Name", "string") +
field("Score", "float64") +
"\n} `json:\"user\"`" +
"\n}",
},
"empty nested object": {
input: `{"user": {}}`,
output: "type Out struct {" +
field("User", "struct {") +
"\n} `json:\"user\"`" +
"\n}",
},
"array of object": {
input: `[{"name": "John"}, {"name": "Jane"}]`,
output: "type Out []struct {" +
field("Name", "string") +
"\n}",
},
"empty array": {
input: `{"items": []}`,
output: "type Out struct {" +
field("Items", "[]any") +
"\n}",
},
"null": {
input: `{"item": null}`,
output: `type Out struct {` +
field("Item", "any") +
"\n}",
},
"numbers": {
input: `{"pos": 123, "neg": -321, "float": 420.69}`,
output: "type Out struct {" +
field("Float", "float64") +
field("Neg", "int") +
field("Pos", "int") +
"\n}",
},
}
trans := NewTransformer()
for tname, tt := range tests {
t.Run(tname, func(t *testing.T) {
result, err := trans.Transform("Out", tt.input)
assertEqualErr(t, tt.err, err)
assertEqual(t, tt.output, result)
})
}
}
func assertEqualErr(t *testing.T, expected, actual error) {
t.Helper()
if (expected != nil || actual != nil) && errors.Is(expected, actual) {
t.Errorf("expected: %v, got: %v\n", expected, actual)
}
}
func assertEqual[T any](t *testing.T, expected, actual T) {
t.Helper()
if !reflect.DeepEqual(expected, actual) {
t.Errorf("expected: %v, got: %v\n", expected, actual)
}
}
|