11 "github.com/stretchr/testify/assert"
13 cmn "github.com/tendermint/tmlibs/common"
16 type SimpleStruct struct {
22 type Animal interface{}
42 var _ = RegisterInterface(
44 ConcreteType{Cat{}, 0x01},
45 ConcreteType{Dog{}, 0x02},
46 ConcreteType{Snake{}, 0x03},
47 ConcreteType{&Viper{}, 0x04},
50 func TestTime(t *testing.T) {
52 // panic trying to encode times before 1970
53 panicCases := []time.Time{
58 for _, c := range panicCases {
59 n, err := new(int), new(error)
60 buf := new(bytes.Buffer)
61 assert.Panics(t, func() { WriteBinary(c, buf, n, err) }, "expected WriteBinary to panic on times before 1970")
64 // ensure we can encode/decode a recent time
66 n, err := new(int), new(error)
67 buf := new(bytes.Buffer)
68 WriteBinary(now, buf, n, err)
70 var thisTime time.Time
71 thisTime = ReadBinary(thisTime, buf, 0, new(int), new(error)).(time.Time)
72 if !thisTime.Truncate(time.Millisecond).Equal(now.Truncate(time.Millisecond)) {
73 t.Fatalf("times dont match. got %v, expected %v", thisTime, now)
76 // error trying to decode bad times
77 errorCases := []struct {
81 {time.Time{}, ErrBinaryReadInvalidTimeNegative},
82 {time.Unix(-10, 0), ErrBinaryReadInvalidTimeNegative},
83 {time.Unix(0, -10), ErrBinaryReadInvalidTimeNegative},
85 {time.Unix(0, 10), ErrBinaryReadInvalidTimeSubMillisecond},
86 {time.Unix(1, 10), ErrBinaryReadInvalidTimeSubMillisecond},
88 for _, c := range errorCases {
89 n, err := new(int), new(error)
90 buf := new(bytes.Buffer)
91 timeNano := c.thisTime.UnixNano()
92 WriteInt64(timeNano, buf, n, err)
93 var thisTime time.Time
94 thisTime = ReadBinary(thisTime, buf, 0, n, err).(time.Time)
95 assert.Equal(t, *err, c.err, "expected ReadBinary to throw an error")
96 assert.Equal(t, thisTime, time.Time{}, "expected ReadBinary to return default time")
100 func TestEncodeDecode(t *testing.T) {
101 cat := &Cat{SimpleStruct{String: "cat", Time: time.Now()}}
103 n, err := new(int), new(error)
104 buf := new(bytes.Buffer)
105 WriteBinary(cat, buf, n, err)
107 t.Fatalf("writeBinary:: failed to encode Cat: %v", *err)
111 n, err = new(int), new(error)
112 cat2 = ReadBinary(cat2, buf, 0, n, err).(*Cat)
114 t.Fatalf("unexpected err: %v", *err)
117 // NOTE: this fails because []byte{} != []byte(nil)
118 // assert.Equal(t, cat, cat2, "expected cats to match")
121 func TestUnexportedEmbeddedTypes(t *testing.T) {
122 type unexportedReceiver struct {
126 type exportedReceiver struct {
130 now := time.Now().Truncate(time.Millisecond)
131 origCat := Cat{SimpleStruct{String: "cat", Time: now}}
132 exportedCat := exportedReceiver{origCat} // this is what we encode
133 writeCat := func() *bytes.Buffer {
134 n, err := new(int), new(error)
135 buf := new(bytes.Buffer)
136 WriteBinary(exportedCat, buf, n, err)
138 t.Errorf("writeBinary:: failed to encode Cat: %v", *err)
143 // try to read into unexportedReceiver (should fail)
145 n, err := new(int), new(error)
146 unexp := ReadBinary(unexportedReceiver{}, buf, 0, n, err).(unexportedReceiver)
148 t.Fatalf("unexpected err: %v", *err)
150 returnCat, ok := unexp.animal.(Cat)
152 t.Fatalf("unexpectedly parsed out the Cat type")
155 // try to read into exportedReceiver (should pass)
157 n, err = new(int), new(error)
158 exp := ReadBinary(exportedReceiver{}, buf, 0, n, err).(exportedReceiver)
160 t.Fatalf("unexpected err: %v", *err)
162 returnCat, ok = exp.Animal.(Cat)
164 t.Fatalf("expected to be able to parse out the Cat type; rrecv: %#v", exp.Animal)
168 // NOTE: this fails because []byte{} != []byte(nil)
169 // assert.Equal(t, origCat, returnCat, fmt.Sprintf("cats dont match"))
173 // TODO: add assertions here ...
174 func TestAnimalInterface(t *testing.T) {
177 // Type of pointer to Animal
178 rt := reflect.TypeOf(&foo)
179 fmt.Printf("rt: %v\n", rt)
181 // Type of Animal itself.
182 // NOTE: normally this is acquired through other means
183 // like introspecting on method signatures, or struct fields.
185 fmt.Printf("rte: %v\n", rte)
187 // Get a new pointer to the interface
188 // NOTE: calling .Interface() is to get the actual value,
189 // instead of reflection values.
190 ptr := reflect.New(rte).Interface()
191 fmt.Printf("ptr: %v", ptr)
193 // Make a binary byteslice that represents a *snake.
194 foo = Snake([]byte("snake"))
195 snakeBytes := BinaryBytes(foo)
196 snakeReader := bytes.NewReader(snakeBytes)
198 // Now you can read it.
199 n, err := new(int), new(error)
200 it := ReadBinary(foo, snakeReader, 0, n, err).(Animal)
201 fmt.Println(it, reflect.TypeOf(it))
204 //-------------------------------------
206 type Constructor func() interface{}
207 type Instantiator func() (o interface{}, ptr interface{})
208 type Validator func(o interface{}, t *testing.T)
210 type TestCase struct {
216 //-------------------------------------
218 func constructBasic() interface{} {
222 Bytes: []byte("Bytes"),
223 Time: time.Unix(123, 456789999),
229 func instantiateBasic() (interface{}, interface{}) {
233 func validateBasic(o interface{}, t *testing.T) {
235 if cat.String != "String" {
236 t.Errorf("Expected cat.String == 'String', got %v", cat.String)
238 if string(cat.Bytes) != "Bytes" {
239 t.Errorf("Expected cat.Bytes == 'Bytes', got %X", cat.Bytes)
241 if cat.Time.UnixNano() != 123456000000 { // Only milliseconds
242 t.Errorf("Expected cat.Time.UnixNano() == 123456000000, got %v", cat.Time.UnixNano())
246 //-------------------------------------
248 type NilTestStruct struct {
254 func constructNilTestStruct() interface{} {
255 return NilTestStruct{}
258 func instantiateNilTestStruct() (interface{}, interface{}) {
259 return NilTestStruct{}, &NilTestStruct{}
262 func validateNilTestStruct(o interface{}, t *testing.T) {
263 nts := o.(NilTestStruct)
264 if nts.IntPtr != nil {
265 t.Errorf("Expected nts.IntPtr to be nil, got %v", nts.IntPtr)
267 if nts.CatPtr != nil {
268 t.Errorf("Expected nts.CatPtr to be nil, got %v", nts.CatPtr)
270 if nts.Animal != nil {
271 t.Errorf("Expected nts.Animal to be nil, got %v", nts.Animal)
275 //-------------------------------------
277 type ComplexStruct struct {
282 func constructComplex() interface{} {
285 Animal: constructBasic(),
290 func instantiateComplex() (interface{}, interface{}) {
291 return ComplexStruct{}, &ComplexStruct{}
294 func validateComplex(o interface{}, t *testing.T) {
295 c2 := o.(ComplexStruct)
296 if cat, ok := c2.Animal.(Cat); ok {
297 validateBasic(cat, t)
299 t.Errorf("Expected c2.Animal to be of type cat, got %v", reflect.ValueOf(c2.Animal).Elem().Type())
303 //-------------------------------------
305 type ComplexStruct2 struct {
314 func constructComplex2() interface{} {
315 snake_ := Snake([]byte("hiss"))
322 Bytes: []byte("Bytes"),
329 Bytes: []byte("Bark"),
333 Snake: Snake([]byte("hiss")),
335 Viper: Viper{Bytes: []byte("hizz")},
336 Viper2: &Viper{Bytes: []byte("hizz")},
341 func instantiateComplex2() (interface{}, interface{}) {
342 return ComplexStruct2{}, &ComplexStruct2{}
345 func validateComplex2(o interface{}, t *testing.T) {
346 c2 := o.(ComplexStruct2)
348 if cat.String != "String" {
349 t.Errorf("Expected cat.String == 'String', got %v", cat.String)
351 if string(cat.Bytes) != "Bytes" {
352 t.Errorf("Expected cat.Bytes == 'Bytes', got %X", cat.Bytes)
356 if dog.String != "Woof" {
357 t.Errorf("Expected dog.String == 'Woof', got %v", dog.String)
359 if string(dog.Bytes) != "Bark" {
360 t.Errorf("Expected dog.Bytes == 'Bark', got %X", dog.Bytes)
364 if string(snake) != "hiss" {
365 t.Errorf("Expected string(snake) == 'hiss', got %v", string(snake))
369 if string(*snake2) != "hiss" {
370 t.Errorf("Expected string(snake2) == 'hiss', got %v", string(*snake2))
374 if string(viper.Bytes) != "hizz" {
375 t.Errorf("Expected string(viper.Bytes) == 'hizz', got %v", string(viper.Bytes))
379 if string(viper2.Bytes) != "hizz" {
380 t.Errorf("Expected string(viper2.Bytes) == 'hizz', got %v", string(viper2.Bytes))
384 //-------------------------------------
386 type ComplexStructArray struct {
393 func constructComplexArray() interface{} {
394 c := ComplexStructArray{
399 Bytes: []byte("Bytes"),
406 Bytes: []byte("Bark"),
410 Snake([]byte("hiss")),
412 Bytes: []byte("hizz"),
415 Bytes: [5]byte{1, 10, 50, 100, 200},
416 Ints: [5]int{1, 2, 3, 4, 5},
417 Array: SimpleArray([5]byte{1, 10, 50, 100, 200}),
422 func instantiateComplexArray() (interface{}, interface{}) {
423 return ComplexStructArray{}, &ComplexStructArray{}
426 func validateComplexArray(o interface{}, t *testing.T) {
427 c2 := o.(ComplexStructArray)
428 if cat, ok := c2.Animals[0].(Cat); ok {
429 if cat.String != "String" {
430 t.Errorf("Expected cat.String == 'String', got %v", cat.String)
432 if string(cat.Bytes) != "Bytes" {
433 t.Errorf("Expected cat.Bytes == 'Bytes', got %X", cat.Bytes)
436 t.Errorf("Expected c2.Animals[0] to be of type cat, got %v", reflect.ValueOf(c2.Animals[0]).Elem().Type())
439 if dog, ok := c2.Animals[1].(Dog); ok {
440 if dog.String != "Woof" {
441 t.Errorf("Expected dog.String == 'Woof', got %v", dog.String)
443 if string(dog.Bytes) != "Bark" {
444 t.Errorf("Expected dog.Bytes == 'Bark', got %X", dog.Bytes)
447 t.Errorf("Expected c2.Animals[1] to be of type dog, got %v", reflect.ValueOf(c2.Animals[1]).Elem().Type())
450 if snake, ok := c2.Animals[2].(Snake); ok {
451 if string(snake) != "hiss" {
452 t.Errorf("Expected string(snake) == 'hiss', got %v", string(snake))
455 t.Errorf("Expected c2.Animals[2] to be of type Snake, got %v", reflect.ValueOf(c2.Animals[2]).Elem().Type())
458 if viper, ok := c2.Animals[3].(*Viper); ok {
459 if string(viper.Bytes) != "hizz" {
460 t.Errorf("Expected string(viper.Bytes) == 'hizz', got %v", string(viper.Bytes))
463 t.Errorf("Expected c2.Animals[3] to be of type *Viper, got %v", reflect.ValueOf(c2.Animals[3]).Elem().Type())
467 //-----------------------------------------------------------------------------
469 var testCases = []TestCase{}
472 testCases = append(testCases, TestCase{constructBasic, instantiateBasic, validateBasic})
473 testCases = append(testCases, TestCase{constructComplex, instantiateComplex, validateComplex})
474 testCases = append(testCases, TestCase{constructComplex2, instantiateComplex2, validateComplex2})
475 testCases = append(testCases, TestCase{constructComplexArray, instantiateComplexArray, validateComplexArray})
476 testCases = append(testCases, TestCase{constructNilTestStruct, instantiateNilTestStruct, validateNilTestStruct})
479 func TestBinary(t *testing.T) {
481 for i, testCase := range testCases {
483 t.Log(fmt.Sprintf("Running test case %v", i))
485 // Construct an object
486 o := testCase.Constructor()
489 data := BinaryBytes(o)
490 t.Logf("Binary: %X", data)
492 instance, instancePtr := testCase.Instantiator()
494 // Read onto a struct
495 n, err := new(int), new(error)
496 res := ReadBinary(instance, bytes.NewReader(data), 0, n, err)
498 t.Fatalf("Failed to read into instance: %v", *err)
502 testCase.Validator(res, t)
504 // Read onto a pointer
505 n, err = new(int), new(error)
506 res = ReadBinaryPtr(instancePtr, bytes.NewReader(data), 0, n, err)
508 t.Fatalf("Failed to read into instance: %v", *err)
510 if res != instancePtr {
511 t.Errorf("Expected pointer to pass through")
515 testCase.Validator(reflect.ValueOf(res).Elem().Interface(), t)
517 // Read with len(data)-1 limit should fail.
518 instance, _ = testCase.Instantiator()
519 n, err = new(int), new(error)
520 ReadBinary(instance, bytes.NewReader(data), len(data)-1, n, err)
521 if *err != ErrBinaryReadOverflow {
522 t.Fatalf("Expected ErrBinaryReadOverflow")
525 // Read with len(data) limit should succeed.
526 instance, _ = testCase.Instantiator()
527 n, err = new(int), new(error)
528 ReadBinary(instance, bytes.NewReader(data), len(data), n, err)
530 t.Fatalf("Failed to read instance with sufficient limit: %v", (*err).Error(), *n, len(data), reflect.TypeOf(instance))
536 func TestJSON(t *testing.T) {
538 for i, testCase := range testCases {
540 t.Log(fmt.Sprintf("Running test case %v", i))
542 // Construct an object
543 o := testCase.Constructor()
547 t.Logf("JSON: %v", string(data))
549 instance, instancePtr := testCase.Instantiator()
551 // Read onto a struct
553 res := ReadJSON(instance, data, err)
555 t.Fatalf("Failed to read cat: %v", *err)
559 testCase.Validator(res, t)
561 // Read onto a pointer
562 res = ReadJSON(instancePtr, data, err)
564 t.Fatalf("Failed to read cat: %v", *err)
567 if res != instancePtr {
568 t.Errorf("Expected pointer to pass through")
572 testCase.Validator(reflect.ValueOf(res).Elem().Interface(), t)
577 //------------------------------------------------------------------------------
580 FieldA string `json:"fieldA"` // json field name is "fieldA"
581 FieldB string // json field name is "FieldB"
582 fieldC string // not exported, not serialized.
583 FieldD string `json:",omitempty"` // omit if empty
584 FieldE string `json:",omitempty"` // omit if empty (but won't be)
585 FieldF string `json:"F,omitempty"` // its name is "F", omit if empty
586 FieldG string `json:"G,omitempty"` // its name is "F", omit if empty (but won't be)
589 func TestJSONFieldNames(t *testing.T) {
590 for i := 0; i < 20; i++ { // Try to ensure deterministic success.
595 FieldD: "", // omit because empty
596 FieldE: "e", // no omit, not empty
597 FieldF: "", // omit because empty
598 FieldG: "g", // no omit, not empty
600 stringified := string(JSONBytes(foo))
601 expected := `{"fieldA":"a","FieldB":"b","FieldE":"e","G":"g"}`
602 if stringified != expected {
603 t.Fatalf("JSONFieldNames error: expected %v, got %v",
604 expected, stringified)
609 //------------------------------------------------------------------------------
611 func TestBadAlloc(t *testing.T) {
612 n, err := new(int), new(error)
613 instance := new([]byte)
614 data := cmn.RandBytes(100 * 1024)
615 b := new(bytes.Buffer)
616 // this slice of data claims to be much bigger than it really is
617 WriteUvarint(uint(1<<32-1), b, n, err)
619 res := ReadBinary(instance, b, 0, n, err)
620 fmt.Println(res, *err)
623 //------------------------------------------------------------------------------
625 type SimpleArray [5]byte
627 func TestSimpleArray(t *testing.T) {
630 // Type of pointer to array
631 rt := reflect.TypeOf(&foo)
632 fmt.Printf("rt: %v\n", rt) // *binary.SimpleArray
634 // Type of array itself.
635 // NOTE: normally this is acquired through other means
636 // like introspecting on method signatures, or struct fields.
638 fmt.Printf("rte: %v\n", rte) // binary.SimpleArray
640 // Get a new pointer to the array
641 // NOTE: calling .Interface() is to get the actual value,
642 // instead of reflection values.
643 ptr := reflect.New(rte).Interface()
644 fmt.Printf("ptr: %v\n", ptr) // &[0 0 0 0 0]
646 // Make a simple int aray
647 fooArray := SimpleArray([5]byte{1, 10, 50, 100, 200})
648 fooBytes := BinaryBytes(fooArray)
649 fooReader := bytes.NewReader(fooBytes)
651 // Now you can read it.
652 n, err := new(int), new(error)
653 it := ReadBinary(foo, fooReader, 0, n, err).(SimpleArray)
655 if !bytes.Equal(it[:], fooArray[:]) {
656 t.Errorf("Expected %v but got %v", fooArray, it)
660 //--------------------------------------------------------------------------------
662 func TestNilPointerInterface(t *testing.T) {
664 type MyInterface interface{}
665 type MyConcreteStruct1 struct{}
666 type MyConcreteStruct2 struct{}
669 struct{ MyInterface }{},
670 ConcreteType{&MyConcreteStruct1{}, 0x01},
671 ConcreteType{&MyConcreteStruct2{}, 0x02},
674 type MyStruct struct {
678 myStruct := MyStruct{(*MyConcreteStruct1)(nil)}
679 buf, n, err := new(bytes.Buffer), int(0), error(nil)
680 WriteBinary(myStruct, buf, &n, &err)
682 t.Error("Expected error in writing nil pointer interface")
685 myStruct = MyStruct{&MyConcreteStruct1{}}
686 buf, n, err = new(bytes.Buffer), int(0), error(nil)
687 WriteBinary(myStruct, buf, &n, &err)
689 t.Error("Unexpected error", err)
694 //--------------------------------------------------------------------------------
696 func TestMultipleInterfaces(t *testing.T) {
698 type MyInterface1 interface{}
699 type MyInterface2 interface{}
700 type Struct1 struct{}
701 type Struct2 struct{}
704 struct{ MyInterface1 }{},
705 ConcreteType{&Struct1{}, 0x01},
706 ConcreteType{&Struct2{}, 0x02},
707 ConcreteType{Struct1{}, 0x03},
708 ConcreteType{Struct2{}, 0x04},
711 struct{ MyInterface2 }{},
712 ConcreteType{&Struct1{}, 0x11},
713 ConcreteType{&Struct2{}, 0x12},
714 ConcreteType{Struct1{}, 0x13},
715 ConcreteType{Struct2{}, 0x14},
718 type MyStruct struct {
723 myStruct := MyStruct{
739 buf, n, err := new(bytes.Buffer), int(0), error(nil)
740 WriteBinary(myStruct, buf, &n, &err)
742 t.Error("Unexpected error", err)
744 if hexStr := hex.EncodeToString(buf.Bytes()); hexStr !=
745 "0105"+"0001020304"+"0105"+"0011121314" {
746 t.Error("Unexpected binary bytes", hexStr)
751 myStruct2 := MyStruct{}
752 ReadBinaryPtr(&myStruct2, buf, 0, &n, &err)
754 t.Error("Unexpected error", err)
757 if len(myStruct2.F1) != 5 {
758 t.Error("Expected F1 to have 5 items")
760 if myStruct2.F1[0] != nil {
761 t.Error("Expected F1[0] to be nil")
763 if _, ok := (myStruct2.F1[1]).(*Struct1); !ok {
764 t.Error("Expected F1[1] to be of type *Struct1")
766 if s, _ := (myStruct2.F1[1]).(*Struct1); s == nil {
767 t.Error("Expected F1[1] to be of type *Struct1 but not nil")
769 if _, ok := (myStruct2.F1[2]).(*Struct2); !ok {
770 t.Error("Expected F1[2] to be of type *Struct2")
772 if s, _ := (myStruct2.F1[2]).(*Struct2); s == nil {
773 t.Error("Expected F1[2] to be of type *Struct2 but not nil")
775 if _, ok := (myStruct2.F1[3]).(Struct1); !ok {
776 t.Error("Expected F1[3] to be of type Struct1")
778 if _, ok := (myStruct2.F1[4]).(Struct2); !ok {
779 t.Error("Expected F1[4] to be of type Struct2")
781 if myStruct2.F2[0] != nil {
782 t.Error("Expected F2[0] to be nil")
784 if _, ok := (myStruct2.F2[1]).(*Struct1); !ok {
785 t.Error("Expected F2[1] to be of type *Struct1")
787 if s, _ := (myStruct2.F2[1]).(*Struct1); s == nil {
788 t.Error("Expected F2[1] to be of type *Struct1 but not nil")
790 if _, ok := (myStruct2.F2[2]).(*Struct2); !ok {
791 t.Error("Expected F2[2] to be of type *Struct2")
793 if s, _ := (myStruct2.F2[2]).(*Struct2); s == nil {
794 t.Error("Expected F2[2] to be of type *Struct2 but not nil")
796 if _, ok := (myStruct2.F2[3]).(Struct1); !ok {
797 t.Error("Expected F2[3] to be of type Struct1")
799 if _, ok := (myStruct2.F2[4]).(Struct2); !ok {
800 t.Error("Expected F2[4] to be of type Struct2")
805 //--------------------------------------------------------------------------------
807 func TestPointers(t *testing.T) {
809 type Struct1 struct {
813 type MyStruct struct {
818 myStruct := MyStruct{
822 buf, n, err := new(bytes.Buffer), int(0), error(nil)
823 WriteBinary(myStruct, buf, &n, &err)
825 t.Error("Unexpected error", err)
827 if hexStr := hex.EncodeToString(buf.Bytes()); hexStr !=
829 t.Error("Unexpected binary bytes", hexStr)
834 myStruct2 := MyStruct{}
835 ReadBinaryPtr(&myStruct2, buf, 0, &n, &err)
837 t.Error("Unexpected error", err)
840 if myStruct2.F1 != nil {
841 t.Error("Expected F1 to be nil")
843 if myStruct2.F2.Foo != 8 {
844 t.Error("Expected F2.Foo to be 8")
849 //--------------------------------------------------------------------------------
851 func TestUnsafe(t *testing.T) {
853 type Struct1 struct {
857 type Struct2 struct {
858 Foo float64 `wire:"unsafe"`
861 myStruct := Struct1{5.32}
862 myStruct2 := Struct2{5.32}
863 buf, n, err := new(bytes.Buffer), int(0), error(nil)
864 WriteBinary(myStruct, buf, &n, &err)
866 t.Error("Expected error due to float without `unsafe`")
869 buf, n, err = new(bytes.Buffer), int(0), error(nil)
870 WriteBinary(myStruct2, buf, &n, &err)
872 t.Error("Unexpected error", err)
876 n, err = int(0), error(nil)
877 ReadBinaryPtr(&s, buf, 0, &n, &err)
879 t.Error("Unexpected error", err)
882 if s.Foo != myStruct2.Foo {
883 t.Error("Expected float values to be the same. Got", s.Foo, "expected", myStruct2.Foo)
888 //--------------------------------------------------------------------------------
890 func TestUnwrap(t *testing.T) {
892 type Result interface{}
893 type ConcreteResult struct{ A int }
896 ConcreteType{&ConcreteResult{}, 0x01},
899 type Struct1 struct {
900 Result Result `json:"unwrap"`
901 other string // this should be ignored, it is unexported
902 Other string `json:"-"` // this should also be ignored
905 myStruct := Struct1{Result: &ConcreteResult{5}}
906 buf, n, err := new(bytes.Buffer), int(0), error(nil)
907 WriteJSON(myStruct, buf, &n, &err)
909 t.Error("Unexpected error", err)
911 jsonBytes := buf.Bytes()
912 if string(jsonBytes) != `[1,{"A":5}]` {
913 t.Error("Unexpected jsonBytes", string(jsonBytes))
918 ReadJSON(&s, jsonBytes, &err)
920 t.Error("Unexpected error", err)
923 sConcrete, ok := s.Result.(*ConcreteResult)
925 t.Error("Expected struct result to be of type ConcreteResult. Got", reflect.TypeOf(s.Result))
929 expected := myStruct.Result.(*ConcreteResult).A
931 t.Error("Expected values to match. Got", got, "expected", expected)