| package util |
| |
| import ( |
| "bytes" |
| "encoding/gob" |
| "fmt" |
| "testing" |
| |
| "github.com/stretchr/testify/assert" |
| "go.skia.org/infra/go/deepequal/assertdeep" |
| ) |
| |
| type Item struct { |
| Id string |
| Map map[string]string |
| Slice []string |
| } |
| |
| func TestGobEncoder(t *testing.T) { |
| // TODO(benjaminwagner): Is there any way to cause an error? |
| e := GobEncoder{} |
| expectedItems := map[*Item][]byte{} |
| for i := 0; i < 25; i++ { |
| item := &Item{} |
| item.Id = fmt.Sprintf("Id-%d", i) |
| item.Map = map[string]string{"PointA": "PointB"} |
| item.Slice = []string{"bread"} |
| var buf bytes.Buffer |
| err := gob.NewEncoder(&buf).Encode(item) |
| assert.NoError(t, err) |
| expectedItems[item] = buf.Bytes() |
| assert.True(t, e.Process(item)) |
| } |
| |
| actualItems := map[*Item][]byte{} |
| for item, serialized, err := e.Next(); item != nil; item, serialized, err = e.Next() { |
| assert.NoError(t, err) |
| actualItems[item.(*Item)] = serialized |
| } |
| |
| assertdeep.Equal(t, expectedItems, actualItems) |
| } |
| |
| func TestGobEncoderNoItems(t *testing.T) { |
| e := GobEncoder{} |
| item, serialized, err := e.Next() |
| assert.NoError(t, err) |
| assert.Nil(t, item) |
| assert.Nil(t, serialized) |
| } |
| |
| func TestGobDecoder(t *testing.T) { |
| d := NewGobDecoder(func() interface{} { |
| return &Item{} |
| }, func(ch <-chan interface{}) interface{} { |
| items := []*Item{} |
| for item := range ch { |
| items = append(items, item.(*Item)) |
| } |
| return items |
| }) |
| expectedItems := map[string]*Item{} |
| for i := 0; i < 250; i++ { |
| item := &Item{} |
| item.Id = fmt.Sprintf("Id-%d", i) |
| item.Map = map[string]string{"PointA": "PointB"} |
| item.Slice = []string{"bread"} |
| var buf bytes.Buffer |
| err := gob.NewEncoder(&buf).Encode(item) |
| assert.NoError(t, err) |
| expectedItems[item.Id] = item |
| assert.True(t, d.Process(buf.Bytes())) |
| } |
| |
| actualItems := map[string]*Item{} |
| iResult, err := d.Result() |
| assert.NoError(t, err) |
| result := iResult.([]*Item) |
| assert.Equal(t, len(expectedItems), len(result)) |
| for _, item := range result { |
| actualItems[item.Id] = item |
| } |
| assertdeep.Equal(t, expectedItems, actualItems) |
| } |
| |
| func TestGobDecoderNoItems(t *testing.T) { |
| d := NewGobDecoder(func() interface{} { |
| return &Item{} |
| }, func(ch <-chan interface{}) interface{} { |
| items := []*Item{} |
| for item := range ch { |
| items = append(items, item.(*Item)) |
| } |
| return items |
| }) |
| result, err := d.Result() |
| assert.NoError(t, err) |
| assert.Equal(t, 0, len(result.([]*Item))) |
| } |
| |
| func TestGobDecoderError(t *testing.T) { |
| item := &Item{} |
| item.Id = "Id" |
| var buf bytes.Buffer |
| err := gob.NewEncoder(&buf).Encode(item) |
| assert.NoError(t, err) |
| serialized := buf.Bytes() |
| invalid := append([]byte("Hi Mom!"), serialized...) |
| |
| d := NewGobDecoder(func() interface{} { |
| return &Item{} |
| }, func(ch <-chan interface{}) interface{} { |
| items := []*Item{} |
| for item := range ch { |
| items = append(items, item.(*Item)) |
| } |
| return items |
| }) |
| // Process should return true before it encounters an invalid result. |
| assert.True(t, d.Process(serialized)) |
| assert.True(t, d.Process(serialized)) |
| // Process may return true or false after encountering an invalid value. |
| _ = d.Process(invalid) |
| for i := 0; i < 250; i++ { |
| _ = d.Process(serialized) |
| } |
| |
| // Result should return error. |
| result, err := d.Result() |
| assert.Error(t, err) |
| assert.Nil(t, result) |
| } |