func TestMarshal(t *testing.T) {
	var nilInterface interface{}
	var testChan chan int
	var testFunc func()
	var testComplex64 complex64
	var testComplex128 complex128
	testInterface := interface{}(17)
	structMarshalTestIn := allTypesTest{
		127,                                 
		255,                                 
		32767,                               
		65535,                               
		2147483647,                          
		4294967295,                          
		9223372036854775807,                 
		18446744073709551615,                
		true,                                
		3.14,                                
		3.141592653589793,                   
		"xdr",                               
		[]byte{1, 2, 3, 4},                  
		[3]byte{1, 2, 3},                    
		[]int16{512, 1024, 2048},            
		[2]subTest{{"one", 1}, {"two", 2}},  
		subTest{"bar", 3},                   
		map[string]uint32{"map1": 1},        
		time.Unix(1396581888, 0).UTC(),      
	}
	structMarshalTestWant := []byte{
		0x00, 0x00, 0x00, 0x7F,  
		0x00, 0x00, 0x00, 0xFF,  
		0x00, 0x00, 0x7F, 0xFF,  
		0x00, 0x00, 0xFF, 0xFF,  
		0x7F, 0xFF, 0xFF, 0xFF,  
		0xFF, 0xFF, 0xFF, 0xFF,  
		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
		0x00, 0x00, 0x00, 0x01,  
		0x40, 0x48, 0xF5, 0xC3,  
		0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,  
		0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00,  
		0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04,  
		0x01, 0x02, 0x03, 0x00,  
		0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00,
		0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00,  
		0x00, 0x00, 0x00, 0x03, 0x6F, 0x6E, 0x65, 0x00,  
		0x00, 0x00, 0x00, 0x01,  
		0x00, 0x00, 0x00, 0x03, 0x74, 0x77, 0x6F, 0x00,  
		0x00, 0x00, 0x00, 0x02,  
		0x00, 0x00, 0x00, 0x03, 0x62, 0x61, 0x72, 0x00,  
		0x00, 0x00, 0x00, 0x03,  
		0x00, 0x00, 0x00, 0x01,  
		0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31,  
		0x00, 0x00, 0x00, 0x01,  
		0x00, 0x00, 0x00, 0x14, 0x32, 0x30, 0x31, 0x34,
		0x2d, 0x30, 0x34, 0x2d, 0x30, 0x34, 0x54, 0x30,
		0x33, 0x3a, 0x32, 0x34, 0x3a, 0x34, 0x38, 0x5a,  
	}
	tests := []struct {
		in   interface{}
		want []byte
		err  error
	}{
		{testInterface, []byte{0x00, 0x00, 0x00, 0x11}, nil},
		{&testInterface, []byte{0x00, 0x00, 0x00, 0x11}, nil},
		{int8(0), []byte{0x00, 0x00, 0x00, 0x00}, nil},
		{int8(64), []byte{0x00, 0x00, 0x00, 0x40}, nil},
		{int8(127), []byte{0x00, 0x00, 0x00, 0x7F}, nil},
		{int8(-1), []byte{0xFF, 0xFF, 0xFF, 0xFF}, nil},
		{int8(-128), []byte{0xFF, 0xFF, 0xFF, 0x80}, nil},
		{uint8(0), []byte{0x00, 0x00, 0x00, 0x00}, nil},
		{uint8(64), []byte{0x00, 0x00, 0x00, 0x40}, nil},
		{uint8(255), []byte{0x00, 0x00, 0x00, 0xFF}, nil},
		{int16(0), []byte{0x00, 0x00, 0x00, 0x00}, nil},
		{int16(1024), []byte{0x00, 0x00, 0x04, 0x00}, nil},
		{int16(32767), []byte{0x00, 0x00, 0x7F, 0xFF}, nil},
		{int16(-1), []byte{0xFF, 0xFF, 0xFF, 0xFF}, nil},
		{int16(-32768), []byte{0xFF, 0xFF, 0x80, 0x00}, nil},
		{uint16(0), []byte{0x00, 0x00, 0x00, 0x00}, nil},
		{uint16(1024), []byte{0x00, 0x00, 0x04, 0x00}, nil},
		{uint16(65535), []byte{0x00, 0x00, 0xFF, 0xFF}, nil},
		{int32(0), []byte{0x00, 0x00, 0x00, 0x00}, nil},
		{int32(262144), []byte{0x00, 0x04, 0x00, 0x00}, nil},
		{int32(2147483647), []byte{0x7F, 0xFF, 0xFF, 0xFF}, nil},
		{int32(-1), []byte{0xFF, 0xFF, 0xFF, 0xFF}, nil},
		{int32(-2147483648), []byte{0x80, 0x00, 0x00, 0x00}, nil},
		{uint32(0), []byte{0x00, 0x00, 0x00, 0x00}, nil},
		{uint32(262144), []byte{0x00, 0x04, 0x00, 0x00}, nil},
		{uint32(4294967295), []byte{0xFF, 0xFF, 0xFF, 0xFF}, nil},
		{int64(0), []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, nil},
		{int64(1 << 34), []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, nil},
		{int64(1 << 42), []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, nil},
		{int64(9223372036854775807), []byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nil},
		{int64(-1), []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nil},
		{int64(-9223372036854775808), []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, nil},
		{uint64(0), []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, nil},
		{uint64(1 << 34), []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, nil},
		{uint64(1 << 42), []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, nil},
		{uint64(18446744073709551615), []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nil},
		{uint64(9223372036854775808), []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, nil},
		{false, []byte{0x00, 0x00, 0x00, 0x00}, nil},
		{true, []byte{0x00, 0x00, 0x00, 0x01}, nil},
		{float32(0), []byte{0x00, 0x00, 0x00, 0x00}, nil},
		{float32(3.14), []byte{0x40, 0x48, 0xF5, 0xC3}, nil},
		{float32(1234567.0), []byte{0x49, 0x96, 0xB4, 0x38}, nil},
		{float32(math.Inf(-1)), []byte{0xFF, 0x80, 0x00, 0x00}, nil},
		{float32(math.Inf(0)), []byte{0x7F, 0x80, 0x00, 0x00}, nil},
		{float64(0), []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, nil},
		{float64(3.141592653589793), []byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}, nil},
		{float64(math.Inf(-1)), []byte{0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, nil},
		{float64(math.Inf(0)), []byte{0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, nil},
		{"", []byte{0x00, 0x00, 0x00, 0x00}, nil},
		{"xdr", []byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, nil},
		{"τ=2π", []byte{0x00, 0x00, 0x00, 0x06, 0xCF, 0x84, 0x3D, 0x32, 0xCF, 0x80, 0x00, 0x00}, nil},
		{[]byte{0x01}, []byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, nil},
		{[]byte{0x01, 0x02, 0x03}, []byte{0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00}, nil},
		{[1]byte{0x01}, []byte{0x01, 0x00, 0x00, 0x00}, nil},  
		{&[2]byte{0x01, 0x02}, []byte{0x01, 0x02, 0x00, 0x00}, nil},
		{&[3]byte{0x01, 0x02, 0x03}, []byte{0x01, 0x02, 0x03, 0x00}, nil},
		{&[4]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil},
		{&[5]byte{0x01, 0x02, 0x03, 0x04, 0x05}, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00}, nil},
		{&[]int16{512, 1024, 2048},
			[]byte{0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00},
			nil},
		{[]bool{true, false}, []byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}, nil},
		{&[2]uint32{512, 1024}, []byte{0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00}, nil},
		{map[string]uint32{"map1": 1},
			[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, 0x00, 0x00, 0x00, 0x01},
			nil},
		{time.Unix(1396581888, 0).UTC(),
			[]byte{
				0x00, 0x00, 0x00, 0x14, 0x32, 0x30, 0x31, 0x34,
				0x2d, 0x30, 0x34, 0x2d, 0x30, 0x34, 0x54, 0x30,
				0x33, 0x3a, 0x32, 0x34, 0x3a, 0x34, 0x38, 0x5a,
			}, nil},
		{&structMarshalTestIn, structMarshalTestWant, nil},
		{nilInterface, nil, &MarshalError{ErrorCode: ErrNilInterface}},
		{&nilInterface, nil, &MarshalError{ErrorCode: ErrNilInterface}},
		{testChan, nil, &MarshalError{ErrorCode: ErrUnsupportedType}},
		{&testChan, nil, &MarshalError{ErrorCode: ErrUnsupportedType}},
		{testFunc, nil, &MarshalError{ErrorCode: ErrUnsupportedType}},
		{&testFunc, nil, &MarshalError{ErrorCode: ErrUnsupportedType}},
		{testComplex64, nil, &MarshalError{ErrorCode: ErrUnsupportedType}},
		{&testComplex64, nil, &MarshalError{ErrorCode: ErrUnsupportedType}},
		{testComplex128, nil, &MarshalError{ErrorCode: ErrUnsupportedType}},
		{&testComplex128, nil, &MarshalError{ErrorCode: ErrUnsupportedType}},
	}
	for i, test := range tests {
		rv, err := Marshal(test.in)
		if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
			t.Errorf("Marshal #%d failed to detect error - got: %v <%T> want: %T",
				i, err, err, test.err)
			continue
		}
		if rerr, ok := err.(*MarshalError); ok {
			if terr, ok := test.err.(*MarshalError); ok {
				if rerr.ErrorCode != terr.ErrorCode {
					t.Errorf("Marshal #%d failed to detect error code - got: %v want: %v",
						i, rerr.ErrorCode, terr.ErrorCode)
					continue
				}
				continue
			}
		}
		if len(rv) != len(test.want) {
			t.Errorf("Marshal #%d len got: %v want: %v\n", i, len(rv), len(test.want))
			continue
		}
		if !reflect.DeepEqual(rv, test.want) {
			t.Errorf("Marshal #%d got: %v want: %v\n", i, rv, test.want)
			continue
		}
	}
}
TestMarshal executes all of the tests described by marshalTests.
package xdr
import (
	"fmt"
	"math"
	"reflect"
	"testing"
	"time"
)