1 package runtime_test
2
3 import (
4 "bytes"
5 "encoding/json"
6 "reflect"
7 "strings"
8 "testing"
9
10 "github.com/golang/protobuf/proto"
11 "github.com/golang/protobuf/ptypes/empty"
12 structpb "github.com/golang/protobuf/ptypes/struct"
13 "github.com/golang/protobuf/ptypes/timestamp"
14 "github.com/golang/protobuf/ptypes/wrappers"
15 "github.com/grpc-ecosystem/grpc-gateway/runtime"
16 "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb"
17 )
18
19 func TestJSONBuiltinMarshal(t *testing.T) {
20 var m runtime.JSONBuiltin
21 msg := examplepb.SimpleMessage{
22 Id: "foo",
23 }
24
25 buf, err := m.Marshal(&msg)
26 if err != nil {
27 t.Errorf("m.Marshal(%v) failed with %v; want success", &msg, err)
28 }
29
30 var got examplepb.SimpleMessage
31 if err := json.Unmarshal(buf, &got); err != nil {
32 t.Errorf("json.Unmarshal(%q, &got) failed with %v; want success", buf, err)
33 }
34 if want := msg; !reflect.DeepEqual(got, want) {
35 t.Errorf("got = %v; want %v", &got, &want)
36 }
37 }
38
39 func TestJSONBuiltinMarshalField(t *testing.T) {
40 var m runtime.JSONBuiltin
41 for _, fixt := range builtinFieldFixtures {
42 buf, err := m.Marshal(fixt.data)
43 if err != nil {
44 t.Errorf("m.Marshal(%v) failed with %v; want success", fixt.data, err)
45 }
46 if got, want := string(buf), fixt.json; got != want {
47 t.Errorf("got = %q; want %q; data = %#v", got, want, fixt.data)
48 }
49 }
50 }
51
52 func TestJSONBuiltinMarshalFieldKnownErrors(t *testing.T) {
53 var m runtime.JSONBuiltin
54 for _, fixt := range builtinKnownErrors {
55 buf, err := m.Marshal(fixt.data)
56 if err != nil {
57 t.Errorf("m.Marshal(%v) failed with %v; want success", fixt.data, err)
58 }
59 if got, want := string(buf), fixt.json; got == want {
60 t.Errorf("surprisingly got = %q; as want %q; data = %#v", got, want, fixt.data)
61 }
62 }
63 }
64
65 func TestJSONBuiltinsnmarshal(t *testing.T) {
66 var (
67 m runtime.JSONBuiltin
68 got examplepb.SimpleMessage
69
70 data = []byte(`{"id": "foo"}`)
71 )
72 if err := m.Unmarshal(data, &got); err != nil {
73 t.Errorf("m.Unmarshal(%q, &got) failed with %v; want success", data, err)
74 }
75
76 want := examplepb.SimpleMessage{
77 Id: "foo",
78 }
79 if !reflect.DeepEqual(got, want) {
80 t.Errorf("got = %v; want = %v", &got, &want)
81 }
82 }
83
84 func TestJSONBuiltinUnmarshalField(t *testing.T) {
85 var m runtime.JSONBuiltin
86 for _, fixt := range builtinFieldFixtures {
87 dest := alloc(reflect.TypeOf(fixt.data))
88 if err := m.Unmarshal([]byte(fixt.json), dest.Interface()); err != nil {
89 t.Errorf("m.Unmarshal(%q, dest) failed with %v; want success", fixt.json, err)
90 }
91
92 if got, want := dest.Elem().Interface(), fixt.data; !reflect.DeepEqual(got, want) {
93 t.Errorf("got = %#v; want = %#v; input = %q", got, want, fixt.json)
94 }
95 }
96 }
97
98 func alloc(t reflect.Type) reflect.Value {
99 if t == nil {
100 return reflect.ValueOf(new(interface{}))
101 } else {
102 return reflect.New(t)
103 }
104 }
105
106 func TestJSONBuiltinUnmarshalFieldKnownErrors(t *testing.T) {
107 var m runtime.JSONBuiltin
108 for _, fixt := range builtinKnownErrors {
109 dest := reflect.New(reflect.TypeOf(fixt.data))
110 if err := m.Unmarshal([]byte(fixt.json), dest.Interface()); err == nil {
111 t.Errorf("m.Unmarshal(%q, dest) succeeded; want ane error", fixt.json)
112 }
113 }
114 }
115
116 func TestJSONBuiltinEncoder(t *testing.T) {
117 var m runtime.JSONBuiltin
118 msg := examplepb.SimpleMessage{
119 Id: "foo",
120 }
121
122 var buf bytes.Buffer
123 enc := m.NewEncoder(&buf)
124 if err := enc.Encode(&msg); err != nil {
125 t.Errorf("enc.Encode(%v) failed with %v; want success", &msg, err)
126 }
127
128 var got examplepb.SimpleMessage
129 if err := json.Unmarshal(buf.Bytes(), &got); err != nil {
130 t.Errorf("json.Unmarshal(%q, &got) failed with %v; want success", buf.String(), err)
131 }
132 if want := msg; !reflect.DeepEqual(got, want) {
133 t.Errorf("got = %v; want %v", &got, &want)
134 }
135 }
136
137 func TestJSONBuiltinEncoderFields(t *testing.T) {
138 var m runtime.JSONBuiltin
139 for _, fixt := range builtinFieldFixtures {
140 var buf bytes.Buffer
141 enc := m.NewEncoder(&buf)
142 if err := enc.Encode(fixt.data); err != nil {
143 t.Errorf("enc.Encode(%#v) failed with %v; want success", fixt.data, err)
144 }
145
146 if got, want := buf.String(), fixt.json+"\n"; got != want {
147 t.Errorf("got = %q; want %q; data = %#v", got, want, fixt.data)
148 }
149 }
150 }
151
152 func TestJSONBuiltinDecoder(t *testing.T) {
153 var (
154 m runtime.JSONBuiltin
155 got examplepb.SimpleMessage
156
157 data = `{"id": "foo"}`
158 )
159 r := strings.NewReader(data)
160 dec := m.NewDecoder(r)
161 if err := dec.Decode(&got); err != nil {
162 t.Errorf("m.Unmarshal(&got) failed with %v; want success", err)
163 }
164
165 want := examplepb.SimpleMessage{
166 Id: "foo",
167 }
168 if !reflect.DeepEqual(got, want) {
169 t.Errorf("got = %v; want = %v", &got, &want)
170 }
171 }
172
173 func TestJSONBuiltinDecoderFields(t *testing.T) {
174 var m runtime.JSONBuiltin
175 for _, fixt := range builtinFieldFixtures {
176 r := strings.NewReader(fixt.json)
177 dec := m.NewDecoder(r)
178 dest := alloc(reflect.TypeOf(fixt.data))
179 if err := dec.Decode(dest.Interface()); err != nil {
180 t.Errorf("dec.Decode(dest) failed with %v; want success; data = %q", err, fixt.json)
181 }
182
183 if got, want := dest.Elem().Interface(), fixt.data; !reflect.DeepEqual(got, want) {
184 t.Errorf("got = %v; want = %v; input = %q", got, want, fixt.json)
185 }
186 }
187 }
188
189 var (
190 builtinFieldFixtures = []struct {
191 data interface{}
192 json string
193 }{
194 {data: "", json: `""`},
195 {data: proto.String(""), json: `""`},
196 {data: "foo", json: `"foo"`},
197 {data: proto.String("foo"), json: `"foo"`},
198 {data: int32(-1), json: "-1"},
199 {data: proto.Int32(-1), json: "-1"},
200 {data: int64(-1), json: "-1"},
201 {data: proto.Int64(-1), json: "-1"},
202 {data: uint32(123), json: "123"},
203 {data: proto.Uint32(123), json: "123"},
204 {data: uint64(123), json: "123"},
205 {data: proto.Uint64(123), json: "123"},
206 {data: float32(-1.5), json: "-1.5"},
207 {data: proto.Float32(-1.5), json: "-1.5"},
208 {data: float64(-1.5), json: "-1.5"},
209 {data: proto.Float64(-1.5), json: "-1.5"},
210 {data: true, json: "true"},
211 {data: proto.Bool(true), json: "true"},
212 {data: (*string)(nil), json: "null"},
213 {data: new(empty.Empty), json: "{}"},
214 {data: examplepb.NumericEnum_ONE, json: "1"},
215 {data: nil, json: "null"},
216 {data: (*string)(nil), json: "null"},
217 {data: []interface{}{nil, "foo", -1.0, 1.234, true}, json: `[null,"foo",-1,1.234,true]`},
218 {
219 data: map[string]interface{}{"bar": nil, "baz": -1.0, "fiz": 1.234, "foo": true},
220 json: `{"bar":null,"baz":-1,"fiz":1.234,"foo":true}`,
221 },
222 {
223 data: (*examplepb.NumericEnum)(proto.Int32(int32(examplepb.NumericEnum_ONE))),
224 json: "1",
225 },
226 }
227 builtinKnownErrors = []struct {
228 data interface{}
229 json string
230 }{
231 {data: examplepb.NumericEnum_ONE, json: "ONE"},
232 {
233 data: (*examplepb.NumericEnum)(proto.Int32(int32(examplepb.NumericEnum_ONE))),
234 json: "ONE",
235 },
236 {
237 data: &examplepb.ABitOfEverything_OneofString{OneofString: "abc"},
238 json: `"abc"`,
239 },
240 {
241 data: ×tamp.Timestamp{
242 Seconds: 1462875553,
243 Nanos: 123000000,
244 },
245 json: `"2016-05-10T10:19:13.123Z"`,
246 },
247 {
248 data: &wrappers.Int32Value{Value: 123},
249 json: "123",
250 },
251 {
252 data: &structpb.Value{
253 Kind: &structpb.Value_StringValue{
254 StringValue: "abc",
255 },
256 },
257 json: `"abc"`,
258 },
259 }
260 )
261
View as plain text