1 package runtime_test
2
3 import (
4 "bytes"
5 "reflect"
6 "strconv"
7 "strings"
8 "testing"
9
10 "github.com/golang/protobuf/jsonpb"
11 "github.com/golang/protobuf/proto"
12 "github.com/golang/protobuf/ptypes/duration"
13 "github.com/golang/protobuf/ptypes/empty"
14 structpb "github.com/golang/protobuf/ptypes/struct"
15 "github.com/golang/protobuf/ptypes/timestamp"
16 "github.com/golang/protobuf/ptypes/wrappers"
17 "github.com/grpc-ecosystem/grpc-gateway/runtime"
18 "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb"
19 )
20
21 func TestJSONPbMarshal(t *testing.T) {
22 msg := examplepb.ABitOfEverything{
23 SingleNested: &examplepb.ABitOfEverything_Nested{},
24 RepeatedStringValue: []string{},
25 MappedStringValue: map[string]string{},
26 MappedNestedValue: map[string]*examplepb.ABitOfEverything_Nested{},
27 RepeatedEnumValue: []examplepb.NumericEnum{},
28 TimestampValue: ×tamp.Timestamp{},
29 Uuid: "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
30 Nested: []*examplepb.ABitOfEverything_Nested{
31 {
32 Name: "foo",
33 Amount: 12345,
34 },
35 },
36 Uint64Value: 0xFFFFFFFFFFFFFFFF,
37 EnumValue: examplepb.NumericEnum_ONE,
38 OneofValue: &examplepb.ABitOfEverything_OneofString{
39 OneofString: "bar",
40 },
41 MapValue: map[string]examplepb.NumericEnum{
42 "a": examplepb.NumericEnum_ONE,
43 "b": examplepb.NumericEnum_ZERO,
44 },
45 RepeatedEnumAnnotation: []examplepb.NumericEnum{},
46 EnumValueAnnotation: examplepb.NumericEnum_ONE,
47 RepeatedStringAnnotation: []string{},
48 RepeatedNestedAnnotation: []*examplepb.ABitOfEverything_Nested{},
49 NestedAnnotation: &examplepb.ABitOfEverything_Nested{},
50 }
51
52 for i, spec := range []struct {
53 enumsAsInts, emitDefaults bool
54 indent string
55 origName bool
56 verifier func(json string)
57 }{
58 {
59 verifier: func(json string) {
60 if strings.ContainsAny(json, " \t\r\n") {
61 t.Errorf("strings.ContainsAny(%q, %q) = true; want false", json, " \t\r\n")
62 }
63 if !strings.Contains(json, "ONE") {
64 t.Errorf(`strings.Contains(%q, "ONE") = false; want true`, json)
65 }
66 if want := "uint64Value"; !strings.Contains(json, want) {
67 t.Errorf(`strings.Contains(%q, %q) = false; want true`, json, want)
68 }
69 },
70 },
71 {
72 enumsAsInts: true,
73 verifier: func(json string) {
74 if strings.Contains(json, "ONE") {
75 t.Errorf(`strings.Contains(%q, "ONE") = true; want false`, json)
76 }
77 },
78 },
79 {
80 emitDefaults: true,
81 verifier: func(json string) {
82 if want := `"sfixed32Value"`; !strings.Contains(json, want) {
83 t.Errorf(`strings.Contains(%q, %q) = false; want true`, json, want)
84 }
85 },
86 },
87 {
88 indent: "\t\t",
89 verifier: func(json string) {
90 if want := "\t\t\"amount\":"; !strings.Contains(json, want) {
91 t.Errorf(`strings.Contains(%q, %q) = false; want true`, json, want)
92 }
93 },
94 },
95 {
96 origName: true,
97 verifier: func(json string) {
98 if want := "uint64_value"; !strings.Contains(json, want) {
99 t.Errorf(`strings.Contains(%q, %q) = false; want true`, json, want)
100 }
101 },
102 },
103 } {
104 m := runtime.JSONPb{
105 EnumsAsInts: spec.enumsAsInts,
106 EmitDefaults: spec.emitDefaults,
107 Indent: spec.indent,
108 OrigName: spec.origName,
109 }
110 buf, err := m.Marshal(&msg)
111 if err != nil {
112 t.Errorf("m.Marshal(%v) failed with %v; want success; spec=%v", &msg, err, spec)
113 }
114
115 var got examplepb.ABitOfEverything
116 if err := jsonpb.UnmarshalString(string(buf), &got); err != nil {
117 t.Errorf("jsonpb.UnmarshalString(%q, &got) failed with %v; want success; spec=%v", string(buf), err, spec)
118 }
119 if want := msg; !reflect.DeepEqual(got, want) {
120 t.Errorf("case %d: got = %v; want %v; spec=%v", i, &got, &want, spec)
121 }
122 if spec.verifier != nil {
123 spec.verifier(string(buf))
124 }
125 }
126 }
127
128 func TestJSONPbMarshalFields(t *testing.T) {
129 var m runtime.JSONPb
130 m.EnumsAsInts = true
131 for _, spec := range builtinFieldFixtures {
132 buf, err := m.Marshal(spec.data)
133 if err != nil {
134 t.Errorf("m.Marshal(%#v) failed with %v; want success", spec.data, err)
135 }
136 if got, want := string(buf), spec.json; got != want {
137 t.Errorf("m.Marshal(%#v) = %q; want %q", spec.data, got, want)
138 }
139 }
140
141 m.EnumsAsInts = false
142 buf, err := m.Marshal(examplepb.NumericEnum_ONE)
143 if err != nil {
144 t.Errorf("m.Marshal(%#v) failed with %v; want success", examplepb.NumericEnum_ONE, err)
145 }
146 if got, want := string(buf), `"ONE"`; got != want {
147 t.Errorf("m.Marshal(%#v) = %q; want %q", examplepb.NumericEnum_ONE, got, want)
148 }
149 }
150
151 func TestJSONPbUnmarshal(t *testing.T) {
152 var (
153 m runtime.JSONPb
154 got examplepb.ABitOfEverything
155 )
156 for i, data := range []string{
157 `{
158 "uuid": "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
159 "nested": [
160 {"name": "foo", "amount": 12345}
161 ],
162 "uint64Value": 18446744073709551615,
163 "enumValue": "ONE",
164 "oneofString": "bar",
165 "mapValue": {
166 "a": 1,
167 "b": 0
168 }
169 }`,
170 `{
171 "uuid": "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
172 "nested": [
173 {"name": "foo", "amount": 12345}
174 ],
175 "uint64Value": "18446744073709551615",
176 "enumValue": "ONE",
177 "oneofString": "bar",
178 "mapValue": {
179 "a": 1,
180 "b": 0
181 }
182 }`,
183 `{
184 "uuid": "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
185 "nested": [
186 {"name": "foo", "amount": 12345}
187 ],
188 "uint64Value": 18446744073709551615,
189 "enumValue": 1,
190 "oneofString": "bar",
191 "mapValue": {
192 "a": 1,
193 "b": 0
194 }
195 }`,
196 } {
197 if err := m.Unmarshal([]byte(data), &got); err != nil {
198 t.Errorf("case %d: m.Unmarshal(%q, &got) failed with %v; want success", i, data, err)
199 }
200
201 want := examplepb.ABitOfEverything{
202 Uuid: "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
203 Nested: []*examplepb.ABitOfEverything_Nested{
204 {
205 Name: "foo",
206 Amount: 12345,
207 },
208 },
209 Uint64Value: 0xFFFFFFFFFFFFFFFF,
210 EnumValue: examplepb.NumericEnum_ONE,
211 OneofValue: &examplepb.ABitOfEverything_OneofString{
212 OneofString: "bar",
213 },
214 MapValue: map[string]examplepb.NumericEnum{
215 "a": examplepb.NumericEnum_ONE,
216 "b": examplepb.NumericEnum_ZERO,
217 },
218 }
219
220 if !reflect.DeepEqual(got, want) {
221 t.Errorf("case %d: got = %v; want = %v", i, &got, &want)
222 }
223 }
224 }
225
226 func TestJSONPbUnmarshalFields(t *testing.T) {
227 var m runtime.JSONPb
228 for _, fixt := range fieldFixtures {
229 if fixt.skipUnmarshal {
230 continue
231 }
232
233 dest := reflect.New(reflect.TypeOf(fixt.data))
234 if err := m.Unmarshal([]byte(fixt.json), dest.Interface()); err != nil {
235 t.Errorf("m.Unmarshal(%q, %T) failed with %v; want success", fixt.json, dest.Interface(), err)
236 }
237 if got, want := dest.Elem().Interface(), fixt.data; !reflect.DeepEqual(got, want) {
238 t.Errorf("dest = %#v; want %#v; input = %v", got, want, fixt.json)
239 }
240 }
241 }
242
243 func TestJSONPbEncoder(t *testing.T) {
244 msg := examplepb.ABitOfEverything{
245 SingleNested: &examplepb.ABitOfEverything_Nested{},
246 RepeatedStringValue: []string{},
247 MappedStringValue: map[string]string{},
248 MappedNestedValue: map[string]*examplepb.ABitOfEverything_Nested{},
249 RepeatedEnumValue: []examplepb.NumericEnum{},
250 TimestampValue: ×tamp.Timestamp{},
251 Uuid: "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
252 Nested: []*examplepb.ABitOfEverything_Nested{
253 {
254 Name: "foo",
255 Amount: 12345,
256 },
257 },
258 Uint64Value: 0xFFFFFFFFFFFFFFFF,
259 OneofValue: &examplepb.ABitOfEverything_OneofString{
260 OneofString: "bar",
261 },
262 MapValue: map[string]examplepb.NumericEnum{
263 "a": examplepb.NumericEnum_ONE,
264 "b": examplepb.NumericEnum_ZERO,
265 },
266 RepeatedEnumAnnotation: []examplepb.NumericEnum{},
267 EnumValueAnnotation: examplepb.NumericEnum_ONE,
268 RepeatedStringAnnotation: []string{},
269 RepeatedNestedAnnotation: []*examplepb.ABitOfEverything_Nested{},
270 NestedAnnotation: &examplepb.ABitOfEverything_Nested{},
271 }
272
273 for i, spec := range []struct {
274 enumsAsInts, emitDefaults bool
275 indent string
276 origName bool
277 verifier func(json string)
278 }{
279 {
280 verifier: func(json string) {
281
282 json = strings.TrimSuffix(json, "\n")
283
284 if strings.ContainsAny(json, " \t\r\n") {
285 t.Errorf("strings.ContainsAny(%q, %q) = true; want false", json, " \t\r\n")
286 }
287 if !strings.Contains(json, "ONE") {
288 t.Errorf(`strings.Contains(%q, "ONE") = false; want true`, json)
289 }
290 if want := "uint64Value"; !strings.Contains(json, want) {
291 t.Errorf(`strings.Contains(%q, %q) = false; want true`, json, want)
292 }
293 },
294 },
295 {
296 enumsAsInts: true,
297 verifier: func(json string) {
298 if strings.Contains(json, "ONE") {
299 t.Errorf(`strings.Contains(%q, "ONE") = true; want false`, json)
300 }
301 },
302 },
303 {
304 emitDefaults: true,
305 verifier: func(json string) {
306 if want := `"sfixed32Value"`; !strings.Contains(json, want) {
307 t.Errorf(`strings.Contains(%q, %q) = false; want true`, json, want)
308 }
309 },
310 },
311 {
312 indent: "\t\t",
313 verifier: func(json string) {
314 if want := "\t\t\"amount\":"; !strings.Contains(json, want) {
315 t.Errorf(`strings.Contains(%q, %q) = false; want true`, json, want)
316 }
317 },
318 },
319 {
320 origName: true,
321 verifier: func(json string) {
322 if want := "uint64_value"; !strings.Contains(json, want) {
323 t.Errorf(`strings.Contains(%q, %q) = false; want true`, json, want)
324 }
325 },
326 },
327 } {
328 m := runtime.JSONPb{
329 EnumsAsInts: spec.enumsAsInts,
330 EmitDefaults: spec.emitDefaults,
331 Indent: spec.indent,
332 OrigName: spec.origName,
333 }
334
335 var buf bytes.Buffer
336 enc := m.NewEncoder(&buf)
337 if err := enc.Encode(&msg); err != nil {
338 t.Errorf("enc.Encode(%v) failed with %v; want success; spec=%v", &msg, err, spec)
339 }
340
341 var got examplepb.ABitOfEverything
342 if err := jsonpb.UnmarshalString(buf.String(), &got); err != nil {
343 t.Errorf("jsonpb.UnmarshalString(%q, &got) failed with %v; want success; spec=%v", buf.String(), err, spec)
344 }
345 if want := msg; !reflect.DeepEqual(got, want) {
346 t.Errorf("case %d: got = %v; want %v; spec=%v", i, &got, &want, spec)
347 }
348 if spec.verifier != nil {
349 spec.verifier(buf.String())
350 }
351 }
352 }
353
354 func TestJSONPbEncoderFields(t *testing.T) {
355 var m runtime.JSONPb
356 for _, fixt := range fieldFixtures {
357 var buf bytes.Buffer
358 enc := m.NewEncoder(&buf)
359 if err := enc.Encode(fixt.data); err != nil {
360 t.Errorf("enc.Encode(%#v) failed with %v; want success", fixt.data, err)
361 }
362 if got, want := buf.String(), fixt.json+string(m.Delimiter()); got != want {
363 t.Errorf("enc.Encode(%#v) = %q; want %q", fixt.data, got, want)
364 }
365 }
366
367 m.EnumsAsInts = true
368 buf, err := m.Marshal(examplepb.NumericEnum_ONE)
369 if err != nil {
370 t.Errorf("m.Marshal(%#v) failed with %v; want success", examplepb.NumericEnum_ONE, err)
371 }
372 if got, want := string(buf), "1"; got != want {
373 t.Errorf("m.Marshal(%#v) = %q; want %q", examplepb.NumericEnum_ONE, got, want)
374 }
375 }
376
377 func TestJSONPbDecoder(t *testing.T) {
378 var (
379 m runtime.JSONPb
380 got examplepb.ABitOfEverything
381 )
382 for _, data := range []string{
383 `{
384 "uuid": "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
385 "nested": [
386 {"name": "foo", "amount": 12345}
387 ],
388 "uint64Value": 18446744073709551615,
389 "enumValue": "ONE",
390 "oneofString": "bar",
391 "mapValue": {
392 "a": 1,
393 "b": 0
394 }
395 }`,
396 `{
397 "uuid": "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
398 "nested": [
399 {"name": "foo", "amount": 12345}
400 ],
401 "uint64Value": "18446744073709551615",
402 "enumValue": "ONE",
403 "oneofString": "bar",
404 "mapValue": {
405 "a": 1,
406 "b": 0
407 }
408 }`,
409 `{
410 "uuid": "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
411 "nested": [
412 {"name": "foo", "amount": 12345}
413 ],
414 "uint64Value": 18446744073709551615,
415 "enumValue": 1,
416 "oneofString": "bar",
417 "mapValue": {
418 "a": 1,
419 "b": 0
420 }
421 }`,
422 } {
423 r := strings.NewReader(data)
424 dec := m.NewDecoder(r)
425 if err := dec.Decode(&got); err != nil {
426 t.Errorf("m.Unmarshal(&got) failed with %v; want success; data=%q", err, data)
427 }
428
429 want := examplepb.ABitOfEverything{
430 Uuid: "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
431 Nested: []*examplepb.ABitOfEverything_Nested{
432 {
433 Name: "foo",
434 Amount: 12345,
435 },
436 },
437 Uint64Value: 0xFFFFFFFFFFFFFFFF,
438 EnumValue: examplepb.NumericEnum_ONE,
439 OneofValue: &examplepb.ABitOfEverything_OneofString{
440 OneofString: "bar",
441 },
442 MapValue: map[string]examplepb.NumericEnum{
443 "a": examplepb.NumericEnum_ONE,
444 "b": examplepb.NumericEnum_ZERO,
445 },
446 }
447 if !reflect.DeepEqual(got, want) {
448 t.Errorf("got = %v; want = %v; data = %v", &got, &want, data)
449 }
450 }
451 }
452
453 func TestJSONPbDecoderFields(t *testing.T) {
454 var m runtime.JSONPb
455 for _, fixt := range fieldFixtures {
456 if fixt.skipUnmarshal {
457 continue
458 }
459
460 dest := reflect.New(reflect.TypeOf(fixt.data))
461 dec := m.NewDecoder(strings.NewReader(fixt.json))
462 if err := dec.Decode(dest.Interface()); err != nil {
463 t.Errorf("dec.Decode(%T) failed with %v; want success; input = %q", dest.Interface(), err, fixt.json)
464 }
465 if got, want := dest.Elem().Interface(), fixt.data; !reflect.DeepEqual(got, want) {
466 t.Errorf("dest = %#v; want %#v; input = %v", got, want, fixt.json)
467 }
468 }
469 }
470
471 func TestJSONPbDecoderUnknownField(t *testing.T) {
472 var (
473 m runtime.JSONPb
474 got examplepb.ABitOfEverything
475 )
476 data := `{
477 "uuid": "6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",
478 "unknownField": "111"
479 }`
480
481 runtime.DisallowUnknownFields()
482
483 r := strings.NewReader(data)
484 dec := m.NewDecoder(r)
485 if err := dec.Decode(&got); err == nil {
486 t.Errorf("m.Unmarshal(&got) not failed; want `unknown field` error; data=%q", data)
487 }
488 }
489
490 var (
491 fieldFixtures = []struct {
492 data interface{}
493 json string
494 skipUnmarshal bool
495 }{
496 {data: int32(1), json: "1"},
497 {data: proto.Int32(1), json: "1"},
498 {data: int64(1), json: "1"},
499 {data: proto.Int64(1), json: "1"},
500 {data: uint32(1), json: "1"},
501 {data: proto.Uint32(1), json: "1"},
502 {data: uint64(1), json: "1"},
503 {data: proto.Uint64(1), json: "1"},
504 {data: "abc", json: `"abc"`},
505 {data: proto.String("abc"), json: `"abc"`},
506 {data: float32(1.5), json: "1.5"},
507 {data: proto.Float32(1.5), json: "1.5"},
508 {data: float64(1.5), json: "1.5"},
509 {data: proto.Float64(1.5), json: "1.5"},
510 {data: true, json: "true"},
511 {data: false, json: "false"},
512 {data: (*string)(nil), json: "null"},
513 {
514 data: examplepb.NumericEnum_ONE,
515 json: `"ONE"`,
516
517 skipUnmarshal: true,
518 },
519 {
520 data: (*examplepb.NumericEnum)(proto.Int32(int32(examplepb.NumericEnum_ONE))),
521 json: `"ONE"`,
522
523 skipUnmarshal: true,
524 },
525
526 {
527 data: map[string]int32{
528 "foo": 1,
529 },
530 json: `{"foo":1}`,
531 },
532 {
533 data: map[string]*examplepb.SimpleMessage{
534 "foo": {Id: "bar"},
535 },
536 json: `{"foo":{"id":"bar"}}`,
537 },
538 {
539 data: map[int32]*examplepb.SimpleMessage{
540 1: {Id: "foo"},
541 },
542 json: `{"1":{"id":"foo"}}`,
543 },
544 {
545 data: map[bool]*examplepb.SimpleMessage{
546 true: {Id: "foo"},
547 },
548 json: `{"true":{"id":"foo"}}`,
549 },
550 {
551 data: &duration.Duration{
552 Seconds: 123,
553 Nanos: 456000000,
554 },
555 json: `"123.456s"`,
556 },
557 {
558 data: ×tamp.Timestamp{
559 Seconds: 1462875553,
560 Nanos: 123000000,
561 },
562 json: `"2016-05-10T10:19:13.123Z"`,
563 },
564 {
565 data: new(empty.Empty),
566 json: "{}",
567 },
568
569
570
571 {
572 data: &structpb.Value{
573 Kind: new(structpb.Value_NullValue),
574 },
575 json: "null",
576 skipUnmarshal: true,
577 },
578 {
579 data: &structpb.Value{
580 Kind: &structpb.Value_NumberValue{
581 NumberValue: 123.4,
582 },
583 },
584 json: "123.4",
585 skipUnmarshal: true,
586 },
587 {
588 data: &structpb.Value{
589 Kind: &structpb.Value_StringValue{
590 StringValue: "abc",
591 },
592 },
593 json: `"abc"`,
594 skipUnmarshal: true,
595 },
596 {
597 data: &structpb.Value{
598 Kind: &structpb.Value_BoolValue{
599 BoolValue: true,
600 },
601 },
602 json: "true",
603 skipUnmarshal: true,
604 },
605 {
606 data: &structpb.Struct{
607 Fields: map[string]*structpb.Value{
608 "foo_bar": {
609 Kind: &structpb.Value_BoolValue{
610 BoolValue: true,
611 },
612 },
613 },
614 },
615 json: `{"foo_bar":true}`,
616 skipUnmarshal: true,
617 },
618
619 {
620 data: &wrappers.BoolValue{Value: true},
621 json: "true",
622 },
623 {
624 data: &wrappers.DoubleValue{Value: 123.456},
625 json: "123.456",
626 },
627 {
628 data: &wrappers.FloatValue{Value: 123.456},
629 json: "123.456",
630 },
631 {
632 data: &wrappers.Int32Value{Value: -123},
633 json: "-123",
634 },
635 {
636 data: &wrappers.Int64Value{Value: -123},
637 json: `"-123"`,
638 },
639 {
640 data: &wrappers.UInt32Value{Value: 123},
641 json: "123",
642 },
643 {
644 data: &wrappers.UInt64Value{Value: 123},
645 json: `"123"`,
646 },
647
648 }
649 )
650
651 func TestJSONPbMarshalResponseBodies(t *testing.T) {
652 for i, spec := range []struct {
653 input interface{}
654 emitDefaults bool
655 verifier func(json string)
656 }{
657 {
658 input: &examplepb.ResponseBodyOut{
659 Response: &examplepb.ResponseBodyOut_Response{Data: "abcdef"},
660 },
661 verifier: func(json string) {
662 expected := `{"response":{"data":"abcdef"}}`
663 if json != expected {
664 t.Errorf("json not equal (%q, %q)", json, expected)
665 }
666 },
667 },
668 {
669 emitDefaults: true,
670 input: &examplepb.ResponseBodyOut{},
671 verifier: func(json string) {
672 expected := `{"response":null}`
673 if json != expected {
674 t.Errorf("json not equal (%q, %q)", json, expected)
675 }
676 },
677 },
678 {
679 input: &examplepb.RepeatedResponseBodyOut_Response{},
680 verifier: func(json string) {
681 expected := `{}`
682 if json != expected {
683 t.Errorf("json not equal (%q, %q)", json, expected)
684 }
685 },
686 },
687 {
688 emitDefaults: true,
689 input: &examplepb.RepeatedResponseBodyOut_Response{},
690 verifier: func(json string) {
691 expected := `{"data":"","type":"UNKNOWN"}`
692 if json != expected {
693 t.Errorf("json not equal (%q, %q)", json, expected)
694 }
695 },
696 },
697 {
698 input: ([]*examplepb.RepeatedResponseBodyOut_Response)(nil),
699 verifier: func(json string) {
700 expected := `null`
701 if json != expected {
702 t.Errorf("json not equal (%q, %q)", json, expected)
703 }
704 },
705 },
706 {
707 emitDefaults: true,
708 input: ([]*examplepb.RepeatedResponseBodyOut_Response)(nil),
709 verifier: func(json string) {
710 expected := `[]`
711 if json != expected {
712 t.Errorf("json not equal (%q, %q)", json, expected)
713 }
714 },
715 },
716 {
717 input: []*examplepb.RepeatedResponseBodyOut_Response{},
718 verifier: func(json string) {
719 expected := `[]`
720 if json != expected {
721 t.Errorf("json not equal (%q, %q)", json, expected)
722 }
723 },
724 },
725 {
726 input: []string{"something"},
727 verifier: func(json string) {
728 expected := `["something"]`
729 if json != expected {
730 t.Errorf("json not equal (%q, %q)", json, expected)
731 }
732 },
733 },
734 {
735 input: []string{},
736 verifier: func(json string) {
737 expected := `[]`
738 if json != expected {
739 t.Errorf("json not equal (%q, %q)", json, expected)
740 }
741 },
742 },
743 {
744 input: ([]string)(nil),
745 verifier: func(json string) {
746 expected := `null`
747 if json != expected {
748 t.Errorf("json not equal (%q, %q)", json, expected)
749 }
750 },
751 },
752 {
753 emitDefaults: true,
754 input: ([]string)(nil),
755 verifier: func(json string) {
756 expected := `[]`
757 if json != expected {
758 t.Errorf("json not equal (%q, %q)", json, expected)
759 }
760 },
761 },
762 {
763 input: []*examplepb.RepeatedResponseBodyOut_Response{
764 &examplepb.RepeatedResponseBodyOut_Response{},
765 &examplepb.RepeatedResponseBodyOut_Response{
766 Data: "abc",
767 Type: examplepb.RepeatedResponseBodyOut_Response_A,
768 },
769 },
770 verifier: func(json string) {
771 expected := `[{},{"data":"abc","type":"A"}]`
772 if json != expected {
773 t.Errorf("json not equal (%q, %q)", json, expected)
774 }
775 },
776 },
777 {
778 emitDefaults: true,
779 input: []*examplepb.RepeatedResponseBodyOut_Response{
780 &examplepb.RepeatedResponseBodyOut_Response{},
781 &examplepb.RepeatedResponseBodyOut_Response{
782 Data: "abc",
783 Type: examplepb.RepeatedResponseBodyOut_Response_B,
784 },
785 },
786 verifier: func(json string) {
787 expected := `[{"data":"","type":"UNKNOWN"},{"data":"abc","type":"B"}]`
788 if json != expected {
789 t.Errorf("json not equal (%q, %q)", json, expected)
790 }
791 },
792 },
793 } {
794
795 t.Run(strconv.Itoa(i), func(t *testing.T) {
796 m := runtime.JSONPb{
797 EmitDefaults: spec.emitDefaults,
798 }
799 val := spec.input
800 buf, err := m.Marshal(val)
801 if err != nil {
802 t.Errorf("m.Marshal(%v) failed with %v; want success; spec=%v", val, err, spec)
803 }
804 if spec.verifier != nil {
805 spec.verifier(string(buf))
806 }
807 })
808 }
809 }
810
View as plain text