2 files changed,
196 insertions(+),
2 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2025-11-26 22:31:34 +0200
Authored at:
2025-11-26 19:58:43 +0200
Change ID:
uvvyyyrzwvvposyqosnyxnoqlsxkmspz
Parent:
1609c23
jump to
| M | json2go.go |
| A | json2go_internal_test.go |
M
json2go.go
··· 49 49 50 50 case []any: 51 51 if len(v) == 0 { 52 - return fmt.Sprintf("type %s []any", t.structName) 52 + return fmt.Sprintf("type %s []any", typeName) 53 53 } 54 54 55 55 type_ := t.getGoType(typeName+"Item", v[0]) ··· 78 78 for _, f := range mapToStructInput(input) { 79 79 fieldName := t.toGoFieldName(f.field) 80 80 if fieldName == "" { 81 - fieldName = "Field" 81 + fieldName = "NotNamedField" 82 + f.field = "NotNamedField" 82 83 } 83 84 84 85 fieldType := t.getGoType(fieldName, f.type_)
A
json2go_internal_test.go
··· 1 +package json2go 2 + 3 +import "testing" 4 + 5 +func TestTransformer_GetGoType(t *testing.T) { 6 + tests := map[string]struct { 7 + value any 8 + fieldName string 9 + output string 10 + }{ 11 + "struct": { 12 + value: map[string]any{ 13 + "username": "user-ovich", 14 + "age": float64(20), 15 + }, 16 + output: "struct {" + 17 + field("Age", "int") + 18 + field("Username", "string") + "\n}", 19 + }, 20 + "empty slice": { 21 + value: make([]any, 0), 22 + output: "[]any", 23 + }, 24 + "slice of ints": { 25 + value: []any{float64(3), float64(123)}, 26 + output: "[]int", 27 + }, 28 + "slice of floats": { 29 + value: []any{float64(3.4), float64(123.3)}, 30 + output: "[]float64", 31 + }, 32 + "slice of strings": { 33 + value: []any{"asdf", "jalkjsd"}, 34 + output: "[]string", 35 + }, 36 + "slice of bool": { 37 + value: []any{false, true, false}, 38 + output: "[]bool", 39 + }, 40 + "int": { 41 + value: float64(1233), 42 + output: "int", 43 + }, 44 + "float64": { 45 + value: float64(1233.23), 46 + output: "float64", 47 + }, 48 + "bool": { 49 + value: false, 50 + output: "bool", 51 + }, 52 + "any": { 53 + value: nil, 54 + output: "any", 55 + }, 56 + } 57 + 58 + trans := NewTransformer() 59 + for tname, tt := range tests { 60 + t.Run(tname, func(t *testing.T) { 61 + t.Parallel() 62 + 63 + fieldName := "field" 64 + if tt.fieldName != "" { 65 + fieldName = tt.fieldName 66 + } 67 + 68 + res := trans.getGoType(fieldName, tt.value) 69 + assertEqual(t, tt.output, res) 70 + }) 71 + } 72 +} 73 + 74 +func TestTransformer_buildStruct(t *testing.T) { 75 + tests := map[string]struct { 76 + input map[string]any 77 + output string 78 + }{ 79 + "simple struct": { 80 + input: map[string]any{ 81 + // only one value, because of the inconsistent ordering of maps 82 + "active": true, 83 + }, 84 + output: "struct {" + 85 + field("Active", "bool", "active") + 86 + "\n}", 87 + }, 88 + "with no named field": { 89 + input: map[string]any{"": "user"}, 90 + output: "struct {" + 91 + field("NotNamedField", "string", "NotNamedField") + 92 + "\n}", 93 + }, 94 + } 95 + 96 + trans := NewTransformer() 97 + for tname, tt := range tests { 98 + t.Run(tname, func(t *testing.T) { 99 + t.Parallel() 100 + 101 + res := trans.buildStruct(tt.input) 102 + assertEqual(t, tt.output, res) 103 + }) 104 + } 105 +} 106 + 107 +func TestTransformer_getTypeAnnotation(t *testing.T) { 108 + c := "type Typeich " 109 + tests := map[string]struct { 110 + input any 111 + output string 112 + }{ 113 + "struct": { 114 + input: map[string]any{"field": false}, 115 + output: c + "struct {" + 116 + field("Field", "bool") + "\n}", 117 + }, 118 + "slice": { 119 + input: []any{"asdf", "jkl;"}, 120 + output: c + "[]string", 121 + }, 122 + "empty slice": { 123 + input: make([]any, 0), 124 + output: c + "[]any", 125 + }, 126 + "string": { 127 + input: "asdf", 128 + output: c + "string", 129 + }, 130 + "int": { 131 + input: float64(123), 132 + output: c + "int", 133 + }, 134 + "float64": { 135 + input: float64(123.69), 136 + output: c + "float64", 137 + }, 138 + "bool": { 139 + input: true, 140 + output: c + "bool", 141 + }, 142 + "any": { 143 + input: nil, 144 + output: c + "any", 145 + }, 146 + } 147 + 148 + trans := NewTransformer() 149 + for tname, tt := range tests { 150 + t.Run(tname, func(t *testing.T) { 151 + t.Parallel() 152 + 153 + res := trans.getTypeAnnotation("Typeich", tt.input) 154 + assertEqual(t, tt.output, res) 155 + }) 156 + } 157 +} 158 + 159 +func TestTransformer_toGoFieldName(t *testing.T) { 160 + tests := map[string]string{ 161 + "input": "Input", 162 + "Input": "Input", 163 + "long_name": "LongName", 164 + "a_lot_of_____": "ALotOf", 165 + "__name": "Name", 166 + } 167 + 168 + trans := NewTransformer() 169 + for input, output := range tests { 170 + t.Run(input, func(t *testing.T) { 171 + t.Parallel() 172 + 173 + res := trans.toGoFieldName(input) 174 + assertEqual(t, output, res) 175 + }) 176 + } 177 +} 178 + 179 +func TestMapToStructInput(t *testing.T) { 180 + inp := map[string]any{ 181 + "field1": nil, 182 + "field2": true, 183 + "a": 123, 184 + "user": map[string]any{}, 185 + } 186 + 187 + assertEqual(t, mapToStructInput(inp), []structInput{ 188 + {"a", 123}, 189 + {"field1", nil}, 190 + {"field2", true}, 191 + {"user", map[string]any{}}, 192 + }) 193 +}