ipld-eth-server/vendor/github.com/tinylib/msgp/msgp/edit_test.go
2018-09-11 16:30:29 -05:00

201 lines
4.4 KiB
Go

package msgp
import (
"bytes"
"reflect"
"testing"
)
func TestRemove(t *testing.T) {
var buf bytes.Buffer
w := NewWriter(&buf)
w.WriteMapHeader(3)
w.WriteString("first")
w.WriteFloat64(-3.1)
w.WriteString("second")
w.WriteString("DELETE ME!!!")
w.WriteString("third")
w.WriteBytes([]byte("blah"))
w.Flush()
raw := Remove("second", buf.Bytes())
m, _, err := ReadMapStrIntfBytes(raw, nil)
if err != nil {
t.Fatal(err)
}
if len(m) != 2 {
t.Errorf("expected %d fields; found %d", 2, len(m))
}
if _, ok := m["first"]; !ok {
t.Errorf("field %q not found", "first")
}
if _, ok := m["third"]; !ok {
t.Errorf("field %q not found", "third")
}
if _, ok := m["second"]; ok {
t.Errorf("field %q (deleted field) still present", "second")
}
}
func TestLocate(t *testing.T) {
var buf bytes.Buffer
en := NewWriter(&buf)
en.WriteMapHeader(2)
en.WriteString("thing_one")
en.WriteString("value_one")
en.WriteString("thing_two")
en.WriteFloat64(2.0)
en.Flush()
field := Locate("thing_one", buf.Bytes())
if len(field) == 0 {
t.Fatal("field not found")
}
if !HasKey("thing_one", buf.Bytes()) {
t.Fatal("field not found")
}
var zbuf bytes.Buffer
w := NewWriter(&zbuf)
w.WriteString("value_one")
w.Flush()
if !bytes.Equal(zbuf.Bytes(), field) {
t.Errorf("got %q; wanted %q", field, zbuf.Bytes())
}
zbuf.Reset()
w.WriteFloat64(2.0)
w.Flush()
field = Locate("thing_two", buf.Bytes())
if len(field) == 0 {
t.Fatal("field not found")
}
if !bytes.Equal(zbuf.Bytes(), field) {
t.Errorf("got %q; wanted %q", field, zbuf.Bytes())
}
field = Locate("nope", buf.Bytes())
if len(field) != 0 {
t.Fatalf("wanted a zero-length returned slice")
}
}
func TestReplace(t *testing.T) {
// there are 4 cases that need coverage:
// - new value is smaller than old value
// - new value is the same size as the old value
// - new value is larger than old, but fits within cap(b)
// - new value is larger than old, and doesn't fit within cap(b)
var buf bytes.Buffer
en := NewWriter(&buf)
en.WriteMapHeader(3)
en.WriteString("thing_one")
en.WriteString("value_one")
en.WriteString("thing_two")
en.WriteFloat64(2.0)
en.WriteString("some_bytes")
en.WriteBytes([]byte("here are some bytes"))
en.Flush()
// same-size replacement
var fbuf bytes.Buffer
w := NewWriter(&fbuf)
w.WriteFloat64(4.0)
w.Flush()
// replace 2.0 with 4.0 in field two
raw := Replace("thing_two", buf.Bytes(), fbuf.Bytes())
if len(raw) == 0 {
t.Fatal("field not found")
}
var err error
m := make(map[string]interface{})
m, _, err = ReadMapStrIntfBytes(raw, m)
if err != nil {
t.Logf("%q", raw)
t.Fatal(err)
}
if !reflect.DeepEqual(m["thing_two"], 4.0) {
t.Errorf("wanted %v; got %v", 4.0, m["thing_two"])
}
// smaller-size replacement
// replace 2.0 with []byte("hi!")
fbuf.Reset()
w.WriteBytes([]byte("hi!"))
w.Flush()
raw = Replace("thing_two", raw, fbuf.Bytes())
if len(raw) == 0 {
t.Fatal("field not found")
}
m, _, err = ReadMapStrIntfBytes(raw, m)
if err != nil {
t.Logf("%q", raw)
t.Fatal(err)
}
if !reflect.DeepEqual(m["thing_two"], []byte("hi!")) {
t.Errorf("wanted %v; got %v", []byte("hi!"), m["thing_two"])
}
// larger-size replacement
fbuf.Reset()
w.WriteBytes([]byte("some even larger bytes than before"))
w.Flush()
raw = Replace("some_bytes", raw, fbuf.Bytes())
if len(raw) == 0 {
t.Logf("%q", raw)
t.Fatal(err)
}
m, _, err = ReadMapStrIntfBytes(raw, m)
if err != nil {
t.Logf("%q", raw)
t.Fatal(err)
}
if !reflect.DeepEqual(m["some_bytes"], []byte("some even larger bytes than before")) {
t.Errorf("wanted %v; got %v", []byte("hello there!"), m["some_bytes"])
}
// identical in-place replacement
field := Locate("some_bytes", raw)
newraw := CopyReplace("some_bytes", raw, field)
if !bytes.Equal(newraw, raw) {
t.Logf("in: %q", raw)
t.Logf("out: %q", newraw)
t.Error("bytes not equal after copyreplace")
}
}
func BenchmarkLocate(b *testing.B) {
var buf bytes.Buffer
en := NewWriter(&buf)
en.WriteMapHeader(3)
en.WriteString("thing_one")
en.WriteString("value_one")
en.WriteString("thing_two")
en.WriteFloat64(2.0)
en.WriteString("thing_three")
en.WriteBytes([]byte("hello!"))
en.Flush()
raw := buf.Bytes()
// bytes/s will be the number of bytes traversed per unit of time
field := Locate("thing_three", raw)
b.SetBytes(int64(len(raw) - len(field)))
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
Locate("thing_three", raw)
}
}