123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798 |
- // Copyright 2011 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // This file contains tests of the GobEncoder/GobDecoder support.
- package gob
- import (
- "bytes"
- "errors"
- "fmt"
- "io"
- "net"
- "strings"
- "testing"
- "time"
- )
- // Types that implement the GobEncoder/Decoder interfaces.
- type ByteStruct struct {
- a byte // not an exported field
- }
- type StringStruct struct {
- s string // not an exported field
- }
- type ArrayStruct struct {
- a [8192]byte // not an exported field
- }
- type Gobber int
- type ValueGobber string // encodes with a value, decodes with a pointer.
- type BinaryGobber int
- type BinaryValueGobber string
- type TextGobber int
- type TextValueGobber string
- // The relevant methods
- func (g *ByteStruct) GobEncode() ([]byte, error) {
- b := make([]byte, 3)
- b[0] = g.a
- b[1] = g.a + 1
- b[2] = g.a + 2
- return b, nil
- }
- func (g *ByteStruct) GobDecode(data []byte) error {
- if g == nil {
- return errors.New("NIL RECEIVER")
- }
- // Expect N sequential-valued bytes.
- if len(data) == 0 {
- return io.EOF
- }
- g.a = data[0]
- for i, c := range data {
- if c != g.a+byte(i) {
- return errors.New("invalid data sequence")
- }
- }
- return nil
- }
- func (g *StringStruct) GobEncode() ([]byte, error) {
- return []byte(g.s), nil
- }
- func (g *StringStruct) GobDecode(data []byte) error {
- // Expect N sequential-valued bytes.
- if len(data) == 0 {
- return io.EOF
- }
- a := data[0]
- for i, c := range data {
- if c != a+byte(i) {
- return errors.New("invalid data sequence")
- }
- }
- g.s = string(data)
- return nil
- }
- func (a *ArrayStruct) GobEncode() ([]byte, error) {
- return a.a[:], nil
- }
- func (a *ArrayStruct) GobDecode(data []byte) error {
- if len(data) != len(a.a) {
- return errors.New("wrong length in array decode")
- }
- copy(a.a[:], data)
- return nil
- }
- func (g *Gobber) GobEncode() ([]byte, error) {
- return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
- }
- func (g *Gobber) GobDecode(data []byte) error {
- _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
- return err
- }
- func (g *BinaryGobber) MarshalBinary() ([]byte, error) {
- return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
- }
- func (g *BinaryGobber) UnmarshalBinary(data []byte) error {
- _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
- return err
- }
- func (g *TextGobber) MarshalText() ([]byte, error) {
- return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
- }
- func (g *TextGobber) UnmarshalText(data []byte) error {
- _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
- return err
- }
- func (v ValueGobber) GobEncode() ([]byte, error) {
- return []byte(fmt.Sprintf("VALUE=%s", v)), nil
- }
- func (v *ValueGobber) GobDecode(data []byte) error {
- _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
- return err
- }
- func (v BinaryValueGobber) MarshalBinary() ([]byte, error) {
- return []byte(fmt.Sprintf("VALUE=%s", v)), nil
- }
- func (v *BinaryValueGobber) UnmarshalBinary(data []byte) error {
- _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
- return err
- }
- func (v TextValueGobber) MarshalText() ([]byte, error) {
- return []byte(fmt.Sprintf("VALUE=%s", v)), nil
- }
- func (v *TextValueGobber) UnmarshalText(data []byte) error {
- _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
- return err
- }
- // Structs that include GobEncodable fields.
- type GobTest0 struct {
- X int // guarantee we have something in common with GobTest*
- G *ByteStruct
- }
- type GobTest1 struct {
- X int // guarantee we have something in common with GobTest*
- G *StringStruct
- }
- type GobTest2 struct {
- X int // guarantee we have something in common with GobTest*
- G string // not a GobEncoder - should give us errors
- }
- type GobTest3 struct {
- X int // guarantee we have something in common with GobTest*
- G *Gobber
- B *BinaryGobber
- T *TextGobber
- }
- type GobTest4 struct {
- X int // guarantee we have something in common with GobTest*
- V ValueGobber
- BV BinaryValueGobber
- TV TextValueGobber
- }
- type GobTest5 struct {
- X int // guarantee we have something in common with GobTest*
- V *ValueGobber
- BV *BinaryValueGobber
- TV *TextValueGobber
- }
- type GobTest6 struct {
- X int // guarantee we have something in common with GobTest*
- V ValueGobber
- W *ValueGobber
- BV BinaryValueGobber
- BW *BinaryValueGobber
- TV TextValueGobber
- TW *TextValueGobber
- }
- type GobTest7 struct {
- X int // guarantee we have something in common with GobTest*
- V *ValueGobber
- W ValueGobber
- BV *BinaryValueGobber
- BW BinaryValueGobber
- TV *TextValueGobber
- TW TextValueGobber
- }
- type GobTestIgnoreEncoder struct {
- X int // guarantee we have something in common with GobTest*
- }
- type GobTestValueEncDec struct {
- X int // guarantee we have something in common with GobTest*
- G StringStruct // not a pointer.
- }
- type GobTestIndirectEncDec struct {
- X int // guarantee we have something in common with GobTest*
- G ***StringStruct // indirections to the receiver.
- }
- type GobTestArrayEncDec struct {
- X int // guarantee we have something in common with GobTest*
- A ArrayStruct // not a pointer.
- }
- type GobTestIndirectArrayEncDec struct {
- X int // guarantee we have something in common with GobTest*
- A ***ArrayStruct // indirections to a large receiver.
- }
- func TestGobEncoderField(t *testing.T) {
- b := new(bytes.Buffer)
- // First a field that's a structure.
- enc := NewEncoder(b)
- err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTest0)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if x.G.a != 'A' {
- t.Errorf("expected 'A' got %c", x.G.a)
- }
- // Now a field that's not a structure.
- b.Reset()
- gobber := Gobber(23)
- bgobber := BinaryGobber(24)
- tgobber := TextGobber(25)
- err = enc.Encode(GobTest3{17, &gobber, &bgobber, &tgobber})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- y := new(GobTest3)
- err = dec.Decode(y)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if *y.G != 23 || *y.B != 24 || *y.T != 25 {
- t.Errorf("expected '23 got %d", *y.G)
- }
- }
- // Even though the field is a value, we can still take its address
- // and should be able to call the methods.
- func TestGobEncoderValueField(t *testing.T) {
- b := new(bytes.Buffer)
- // First a field that's a structure.
- enc := NewEncoder(b)
- err := enc.Encode(&GobTestValueEncDec{17, StringStruct{"HIJKL"}})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTestValueEncDec)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if x.G.s != "HIJKL" {
- t.Errorf("expected `HIJKL` got %s", x.G.s)
- }
- }
- // GobEncode/Decode should work even if the value is
- // more indirect than the receiver.
- func TestGobEncoderIndirectField(t *testing.T) {
- b := new(bytes.Buffer)
- // First a field that's a structure.
- enc := NewEncoder(b)
- s := &StringStruct{"HIJKL"}
- sp := &s
- err := enc.Encode(GobTestIndirectEncDec{17, &sp})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTestIndirectEncDec)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if (***x.G).s != "HIJKL" {
- t.Errorf("expected `HIJKL` got %s", (***x.G).s)
- }
- }
- // Test with a large field with methods.
- func TestGobEncoderArrayField(t *testing.T) {
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- var a GobTestArrayEncDec
- a.X = 17
- for i := range a.A.a {
- a.A.a[i] = byte(i)
- }
- err := enc.Encode(&a)
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTestArrayEncDec)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- for i, v := range x.A.a {
- if v != byte(i) {
- t.Errorf("expected %x got %x", byte(i), v)
- break
- }
- }
- }
- // Test an indirection to a large field with methods.
- func TestGobEncoderIndirectArrayField(t *testing.T) {
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- var a GobTestIndirectArrayEncDec
- a.X = 17
- var array ArrayStruct
- ap := &array
- app := &ap
- a.A = &app
- for i := range array.a {
- array.a[i] = byte(i)
- }
- err := enc.Encode(a)
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTestIndirectArrayEncDec)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- for i, v := range (***x.A).a {
- if v != byte(i) {
- t.Errorf("expected %x got %x", byte(i), v)
- break
- }
- }
- }
- // As long as the fields have the same name and implement the
- // interface, we can cross-connect them. Not sure it's useful
- // and may even be bad but it works and it's hard to prevent
- // without exposing the contents of the object, which would
- // defeat the purpose.
- func TestGobEncoderFieldsOfDifferentType(t *testing.T) {
- // first, string in field to byte in field
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTest0)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if x.G.a != 'A' {
- t.Errorf("expected 'A' got %c", x.G.a)
- }
- // now the other direction, byte in field to string in field
- b.Reset()
- err = enc.Encode(GobTest0{17, &ByteStruct{'X'}})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- y := new(GobTest1)
- err = dec.Decode(y)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if y.G.s != "XYZ" {
- t.Fatalf("expected `XYZ` got %q", y.G.s)
- }
- }
- // Test that we can encode a value and decode into a pointer.
- func TestGobEncoderValueEncoder(t *testing.T) {
- // first, string in field to byte in field
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- err := enc.Encode(GobTest4{17, ValueGobber("hello"), BinaryValueGobber("Καλημέρα"), TextValueGobber("こんにちは")})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTest5)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if *x.V != "hello" || *x.BV != "Καλημέρα" || *x.TV != "こんにちは" {
- t.Errorf("expected `hello` got %s", *x.V)
- }
- }
- // Test that we can use a value then a pointer type of a GobEncoder
- // in the same encoded value. Bug 4647.
- func TestGobEncoderValueThenPointer(t *testing.T) {
- v := ValueGobber("forty-two")
- w := ValueGobber("six-by-nine")
- bv := BinaryValueGobber("1nanocentury")
- bw := BinaryValueGobber("πseconds")
- tv := TextValueGobber("gravitationalacceleration")
- tw := TextValueGobber("π²ft/s²")
- // this was a bug: encoding a GobEncoder by value before a GobEncoder
- // pointer would cause duplicate type definitions to be sent.
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- if err := enc.Encode(GobTest6{42, v, &w, bv, &bw, tv, &tw}); err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTest6)
- if err := dec.Decode(x); err != nil {
- t.Fatal("decode error:", err)
- }
- if got, want := x.V, v; got != want {
- t.Errorf("v = %q, want %q", got, want)
- }
- if got, want := x.W, w; got == nil {
- t.Errorf("w = nil, want %q", want)
- } else if *got != want {
- t.Errorf("w = %q, want %q", *got, want)
- }
- if got, want := x.BV, bv; got != want {
- t.Errorf("bv = %q, want %q", got, want)
- }
- if got, want := x.BW, bw; got == nil {
- t.Errorf("bw = nil, want %q", want)
- } else if *got != want {
- t.Errorf("bw = %q, want %q", *got, want)
- }
- if got, want := x.TV, tv; got != want {
- t.Errorf("tv = %q, want %q", got, want)
- }
- if got, want := x.TW, tw; got == nil {
- t.Errorf("tw = nil, want %q", want)
- } else if *got != want {
- t.Errorf("tw = %q, want %q", *got, want)
- }
- }
- // Test that we can use a pointer then a value type of a GobEncoder
- // in the same encoded value.
- func TestGobEncoderPointerThenValue(t *testing.T) {
- v := ValueGobber("forty-two")
- w := ValueGobber("six-by-nine")
- bv := BinaryValueGobber("1nanocentury")
- bw := BinaryValueGobber("πseconds")
- tv := TextValueGobber("gravitationalacceleration")
- tw := TextValueGobber("π²ft/s²")
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- if err := enc.Encode(GobTest7{42, &v, w, &bv, bw, &tv, tw}); err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTest7)
- if err := dec.Decode(x); err != nil {
- t.Fatal("decode error:", err)
- }
- if got, want := x.V, v; got == nil {
- t.Errorf("v = nil, want %q", want)
- } else if *got != want {
- t.Errorf("v = %q, want %q", *got, want)
- }
- if got, want := x.W, w; got != want {
- t.Errorf("w = %q, want %q", got, want)
- }
- if got, want := x.BV, bv; got == nil {
- t.Errorf("bv = nil, want %q", want)
- } else if *got != want {
- t.Errorf("bv = %q, want %q", *got, want)
- }
- if got, want := x.BW, bw; got != want {
- t.Errorf("bw = %q, want %q", got, want)
- }
- if got, want := x.TV, tv; got == nil {
- t.Errorf("tv = nil, want %q", want)
- } else if *got != want {
- t.Errorf("tv = %q, want %q", *got, want)
- }
- if got, want := x.TW, tw; got != want {
- t.Errorf("tw = %q, want %q", got, want)
- }
- }
- func TestGobEncoderFieldTypeError(t *testing.T) {
- // GobEncoder to non-decoder: error
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := &GobTest2{}
- err = dec.Decode(x)
- if err == nil {
- t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
- }
- if !strings.Contains(err.Error(), "type") {
- t.Fatal("expected type error; got", err)
- }
- // Non-encoder to GobDecoder: error
- b.Reset()
- err = enc.Encode(GobTest2{17, "ABC"})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- y := &GobTest1{}
- err = dec.Decode(y)
- if err == nil {
- t.Fatal("expected decode error for mismatched fields (non-encoder to decoder)")
- }
- if !strings.Contains(err.Error(), "type") {
- t.Fatal("expected type error; got", err)
- }
- }
- // Even though ByteStruct is a struct, it's treated as a singleton at the top level.
- func TestGobEncoderStructSingleton(t *testing.T) {
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- err := enc.Encode(&ByteStruct{'A'})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(ByteStruct)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if x.a != 'A' {
- t.Errorf("expected 'A' got %c", x.a)
- }
- }
- func TestGobEncoderNonStructSingleton(t *testing.T) {
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- var g Gobber = 1234
- err := enc.Encode(&g)
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- var x Gobber
- err = dec.Decode(&x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if x != 1234 {
- t.Errorf("expected 1234 got %d", x)
- }
- }
- func TestGobEncoderIgnoreStructField(t *testing.T) {
- b := new(bytes.Buffer)
- // First a field that's a structure.
- enc := NewEncoder(b)
- err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTestIgnoreEncoder)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if x.X != 17 {
- t.Errorf("expected 17 got %c", x.X)
- }
- }
- func TestGobEncoderIgnoreNonStructField(t *testing.T) {
- b := new(bytes.Buffer)
- // First a field that's a structure.
- enc := NewEncoder(b)
- gobber := Gobber(23)
- bgobber := BinaryGobber(24)
- tgobber := TextGobber(25)
- err := enc.Encode(GobTest3{17, &gobber, &bgobber, &tgobber})
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTestIgnoreEncoder)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if x.X != 17 {
- t.Errorf("expected 17 got %c", x.X)
- }
- }
- func TestGobEncoderIgnoreNilEncoder(t *testing.T) {
- b := new(bytes.Buffer)
- // First a field that's a structure.
- enc := NewEncoder(b)
- err := enc.Encode(GobTest0{X: 18}) // G is nil
- if err != nil {
- t.Fatal("encode error:", err)
- }
- dec := NewDecoder(b)
- x := new(GobTest0)
- err = dec.Decode(x)
- if err != nil {
- t.Fatal("decode error:", err)
- }
- if x.X != 18 {
- t.Errorf("expected x.X = 18, got %v", x.X)
- }
- if x.G != nil {
- t.Errorf("expected x.G = nil, got %v", x.G)
- }
- }
- type gobDecoderBug0 struct {
- foo, bar string
- }
- func (br *gobDecoderBug0) String() string {
- return br.foo + "-" + br.bar
- }
- func (br *gobDecoderBug0) GobEncode() ([]byte, error) {
- return []byte(br.String()), nil
- }
- func (br *gobDecoderBug0) GobDecode(b []byte) error {
- br.foo = "foo"
- br.bar = "bar"
- return nil
- }
- // This was a bug: the receiver has a different indirection level
- // than the variable.
- func TestGobEncoderExtraIndirect(t *testing.T) {
- gdb := &gobDecoderBug0{"foo", "bar"}
- buf := new(bytes.Buffer)
- e := NewEncoder(buf)
- if err := e.Encode(gdb); err != nil {
- t.Fatalf("encode: %v", err)
- }
- d := NewDecoder(buf)
- var got *gobDecoderBug0
- if err := d.Decode(&got); err != nil {
- t.Fatalf("decode: %v", err)
- }
- if got.foo != gdb.foo || got.bar != gdb.bar {
- t.Errorf("got = %q, want %q", got, gdb)
- }
- }
- // Another bug: this caused a crash with the new Go1 Time type.
- // We throw in a gob-encoding array, to test another case of isZero,
- // and a struct containing a nil interface, to test a third.
- type isZeroBug struct {
- T time.Time
- S string
- I int
- A isZeroBugArray
- F isZeroBugInterface
- }
- type isZeroBugArray [2]uint8
- // Receiver is value, not pointer, to test isZero of array.
- func (a isZeroBugArray) GobEncode() (b []byte, e error) {
- b = append(b, a[:]...)
- return b, nil
- }
- func (a *isZeroBugArray) GobDecode(data []byte) error {
- if len(data) != len(a) {
- return io.EOF
- }
- a[0] = data[0]
- a[1] = data[1]
- return nil
- }
- type isZeroBugInterface struct {
- I any
- }
- func (i isZeroBugInterface) GobEncode() (b []byte, e error) {
- return []byte{}, nil
- }
- func (i *isZeroBugInterface) GobDecode(data []byte) error {
- return nil
- }
- func TestGobEncodeIsZero(t *testing.T) {
- x := isZeroBug{time.Unix(1e9, 0), "hello", -55, isZeroBugArray{1, 2}, isZeroBugInterface{}}
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- err := enc.Encode(x)
- if err != nil {
- t.Fatal("encode:", err)
- }
- var y isZeroBug
- dec := NewDecoder(b)
- err = dec.Decode(&y)
- if err != nil {
- t.Fatal("decode:", err)
- }
- if x != y {
- t.Fatalf("%v != %v", x, y)
- }
- }
- func TestGobEncodePtrError(t *testing.T) {
- var err error
- b := new(bytes.Buffer)
- enc := NewEncoder(b)
- err = enc.Encode(&err)
- if err != nil {
- t.Fatal("encode:", err)
- }
- dec := NewDecoder(b)
- err2 := fmt.Errorf("foo")
- err = dec.Decode(&err2)
- if err != nil {
- t.Fatal("decode:", err)
- }
- if err2 != nil {
- t.Fatalf("expected nil, got %v", err2)
- }
- }
- func TestNetIP(t *testing.T) {
- // Encoding of net.IP{1,2,3,4} in Go 1.1.
- enc := []byte{0x07, 0x0a, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04}
- var ip net.IP
- err := NewDecoder(bytes.NewReader(enc)).Decode(&ip)
- if err != nil {
- t.Fatalf("decode: %v", err)
- }
- if ip.String() != "1.2.3.4" {
- t.Errorf("decoded to %v, want 1.2.3.4", ip.String())
- }
- }
|