1
16
17 package value
18
19 import (
20 "reflect"
21 "testing"
22 )
23
24 type CustomValue struct {
25 data []byte
26 }
27
28
29 func (c CustomValue) MarshalJSON() ([]byte, error) {
30 return c.data, nil
31 }
32
33 type CustomPointer struct {
34 data []byte
35 }
36
37
38 func (c *CustomPointer) MarshalJSON() ([]byte, error) {
39 return c.data, nil
40 }
41
42 func TestToUnstructured(t *testing.T) {
43 testcases := []struct {
44 Data string
45 Expected interface{}
46 }{
47 {Data: `null`, Expected: nil},
48 {Data: `true`, Expected: true},
49 {Data: `false`, Expected: false},
50 {Data: `[]`, Expected: []interface{}{}},
51 {Data: `[1]`, Expected: []interface{}{int64(1)}},
52 {Data: `{}`, Expected: map[string]interface{}{}},
53 {Data: `{"a":1}`, Expected: map[string]interface{}{"a": int64(1)}},
54 {Data: `0`, Expected: int64(0)},
55 {Data: `0.0`, Expected: float64(0)},
56 }
57
58 for _, tc := range testcases {
59 tc := tc
60 t.Run(tc.Data, func(t *testing.T) {
61 t.Parallel()
62 custom := []interface{}{
63 CustomValue{data: []byte(tc.Data)},
64 &CustomValue{data: []byte(tc.Data)},
65 &CustomPointer{data: []byte(tc.Data)},
66 }
67 for _, custom := range custom {
68 rv := reflect.ValueOf(custom)
69 result, err := TypeReflectEntryOf(rv.Type()).ToUnstructured(rv)
70 if err != nil {
71 t.Fatal(err)
72 }
73 if !reflect.DeepEqual(result, tc.Expected) {
74 t.Errorf("expected %#v but got %#v", tc.Expected, result)
75 }
76 }
77 })
78 }
79 }
80
81 func TestTypeReflectEntryOf(t *testing.T) {
82 testString := ""
83 tests := map[string]struct {
84 arg interface{}
85 want *TypeReflectCacheEntry
86 }{
87 "StructWithStringField": {
88 arg: struct {
89 F1 string `json:"f1"`
90 }{},
91 want: &TypeReflectCacheEntry{
92 structFields: map[string]*FieldCacheEntry{
93 "f1": {
94 JsonName: "f1",
95 fieldPath: [][]int{{0}},
96 fieldType: reflect.TypeOf(testString),
97 TypeEntry: &TypeReflectCacheEntry{},
98 },
99 },
100 orderedStructFields: []*FieldCacheEntry{
101 {
102 JsonName: "f1",
103 fieldPath: [][]int{{0}},
104 fieldType: reflect.TypeOf(testString),
105 TypeEntry: &TypeReflectCacheEntry{},
106 },
107 },
108 },
109 },
110 "StructWith*StringFieldOmitempty": {
111 arg: struct {
112 F1 *string `json:"f1,omitempty"`
113 }{},
114 want: &TypeReflectCacheEntry{
115 structFields: map[string]*FieldCacheEntry{
116 "f1": {
117 JsonName: "f1",
118 isOmitEmpty: true,
119 fieldPath: [][]int{{0}},
120 fieldType: reflect.TypeOf(&testString),
121 TypeEntry: &TypeReflectCacheEntry{},
122 },
123 },
124 orderedStructFields: []*FieldCacheEntry{
125 {
126 JsonName: "f1",
127 isOmitEmpty: true,
128 fieldPath: [][]int{{0}},
129 fieldType: reflect.TypeOf(&testString),
130 TypeEntry: &TypeReflectCacheEntry{},
131 },
132 },
133 },
134 },
135 "StructWithInlinedField": {
136 arg: struct {
137 F1 string `json:",inline"`
138 }{},
139 want: &TypeReflectCacheEntry{
140 structFields: map[string]*FieldCacheEntry{},
141 orderedStructFields: []*FieldCacheEntry{},
142 },
143 },
144 }
145 for name, tt := range tests {
146 t.Run(name, func(t *testing.T) {
147 if got := TypeReflectEntryOf(reflect.TypeOf(tt.arg)); !reflect.DeepEqual(got, tt.want) {
148 t.Errorf("TypeReflectEntryOf() = %v, want %v", got, tt.want)
149 }
150 })
151 }
152 }
153
View as plain text