diff options
Diffstat (limited to 'binproto_test.go')
-rw-r--r-- | binproto_test.go | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/binproto_test.go b/binproto_test.go new file mode 100644 index 0000000..1a44a3d --- /dev/null +++ b/binproto_test.go @@ -0,0 +1,262 @@ +package binproto + +import ( + "bytes" + "io/ioutil" + "testing" +) + +var data = []byte{ + 0x01, 0x2a, 0x00, // Request(42) + 0x08, // IdKVMap + 0x09, 0x10, // UKey (16) + 0x04, 0x02, 0x00, 0x00, 0x00, 'h', 'i', // Bin(hi) + 0x09, 0x01, // UKey(1) + 0x0a, // BinStream + 0x05, 0x00, 0x00, 0x00, 'h', 'e', 'l', 'l', 'o', // BinStream chunk (hello) + 0x02, 0x00, 0x00, 0x00, ',', ' ', // BinStream chunk (, ) + 0x06, 0x00, 0x00, 0x00, 'w', 'o', 'r', 'l', 'd', '!', // BinStream chunk (world!) + 0xff, 0xff, 0xff, 0xff, // Terminating BinStream + 0x09, 0x02, // UKey(2) + 0x06, // List + 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Number(1) + 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Number(2) + 0x0b, // Term + 0x09, 0x03, // UKey(3) + 0x07, // TextKVMap + 0x04, 0x03, 0x00, 0x00, 0x00, 'f', 'o', 'o', // Bin(foo) + 0x04, 0x03, 0x00, 0x00, 0x00, 'b', 'a', 'r', // Bin(bar) + 0x0b, // Term + 0x09, 0x04, // UKey(4) + 0x0c, 0x00, // UBool(false) + 0x09, 0x05, // UKey(5) + 0x0c, 0x01, // UBool(true) + 0x09, 0x06, // UKey(6) + 0x0d, 0x0a, // UByte(10) + 0x0b} // Term + +func chkUnitType(t *testing.T, recv, expected UnitType) { + if recv != expected { + t.Fatalf("Unit has type %s, %s expected.", recv, expected) + } +} + +func readExpect2(t *testing.T, ur UnitReader, expected UnitType) interface{} { + data, err := ReadExpect(ur, expected) + if err != nil { + t.Fatalf("Error from ReadExpect: %s", err) + } + + return data +} + +func TestReading(t *testing.T) { + r := bytes.NewReader(data) + ur := NewSimpleUnitReader(r) + + data := readExpect2(t, ur, UTRequest) + if code := data.(uint16); code != 42 { + t.Errorf("Request had code %d, not 42.", code) + } + + readExpect2(t, ur, UTIdKVMap) + + idkvp, err := ReadIdKVPair(ur) + if err != nil { + t.Fatalf("Could not read IdKVPair: %s", err) + } + if (idkvp.Key != 16) || (idkvp.ValueType != UTBin) || (!bytes.Equal(idkvp.ValuePayload.([]byte), []byte("hi"))) { + t.Errorf("Wrong idkvp content: %v", idkvp) + } + + idkvp, err = ReadIdKVPair(ur) + if err != nil { + t.Fatalf("Could not read IdKVPair: %s", err) + } + if (idkvp.Key != 1) || (idkvp.ValueType != UTBinStream) { + t.Fatalf("Wrong key or value type: %d, %s", idkvp.Key, idkvp.ValueType) + } + d, err := ioutil.ReadAll(idkvp.ValuePayload.(*BinstreamReader)) + if err != nil { + t.Fatalf("BinstreamReader failed: %s", err) + } + if !bytes.Equal(d, []byte("hello, world!")) { + t.Errorf("Wrong Binstream data: %v", d) + } + + idkvp, err = ReadIdKVPair(ur) + if err != nil { + t.Fatalf("Could not read IdKVPair: %s", err) + } + if (idkvp.Key != 2) || (idkvp.ValueType != UTList) { + t.Fatalf("Wrong key or value type: %d, %s", idkvp.Key, idkvp.ValueType) + } + + if item := readExpect2(t, ur, UTNumber); item.(int64) != 1 { + t.Errorf("Wrong number in list. Want: 1. Got: %d", item.(int64)) + } + + if item := readExpect2(t, ur, UTNumber); item.(int64) != 2 { + t.Errorf("Wrong number in list. Want: 2. Got: %d", item.(int64)) + } + + readExpect2(t, ur, UTTerm) + + idkvp, err = ReadIdKVPair(ur) + if err != nil { + t.Fatalf("Could not read IdKVPair: %s", err) + } + if (idkvp.Key != 3) || (idkvp.ValueType != UTTextKVMap) { + t.Fatalf("Wrong key or value type: %d, %s", idkvp.Key, idkvp.ValueType) + } + + textkvp, err := ReadTextKVPair(ur) + if err != nil { + t.Fatalf("Could not read TextKVPair: %s", err) + } + if (textkvp.Key != "foo") || (textkvp.ValueType != UTBin) || (!bytes.Equal(textkvp.ValuePayload.([]byte), []byte("bar"))) { + t.Errorf("Wrong textkvp content: %v", textkvp) + } + + if _, err = ReadTextKVPair(ur); err != Terminated { + t.Fatal("TextKVMap not terminated?") + } + + idkvp, err = ReadIdKVPair(ur) + if err != nil { + t.Fatalf("Could not read IdKVPair: %s", err) + } + if (idkvp.Key != 4) || (idkvp.ValueType != UTBool) { + t.Fatalf("Wrong key or value type: %d, %s", idkvp.Key, idkvp.ValueType) + } + if idkvp.ValuePayload.(bool) != false { + t.Error("Got true, want false") + } + + idkvp, err = ReadIdKVPair(ur) + if err != nil { + t.Fatalf("Could not read IdKVPair: %s", err) + } + if (idkvp.Key != 5) || (idkvp.ValueType != UTBool) { + t.Fatalf("Wrong key or value type: %d, %s", idkvp.Key, idkvp.ValueType) + } + if idkvp.ValuePayload.(bool) != true { + t.Error("Got false, want true") + } + + idkvp, err = ReadIdKVPair(ur) + if err != nil { + t.Fatalf("Could not read IdKVPair: %s", err) + } + if (idkvp.Key != 6) || (idkvp.ValueType != UTByte) { + t.Fatalf("Wrong key or value type: %d, %s", idkvp.Key, idkvp.ValueType) + } + if val := idkvp.ValuePayload.(byte); val != 10 { + t.Errorf("Got byte %d, want 10.", val) + } + + if _, err = ReadIdKVPair(ur); err != Terminated { + t.Fatal("IdKVMap not terminated?") + } +} + +func chkerr(t *testing.T, err error, whatfailed string) { + if err != nil { + t.Fatalf("%s failed: %s", whatfailed, err) + } +} + +func TestWriting(t *testing.T) { + w := new(bytes.Buffer) + + chkerr(t, InitRequest(w, 42), "InitRequest") + chkerr(t, InitIdKVMap(w), "InitIdKVMap") + + chkerr(t, SendUKey(w, 16), "SendUKey") + chkerr(t, SendBin(w, []byte("hi")), "SendBin") + + chkerr(t, SendUKey(w, 1), "SendUKey") + + bsw, err := InitBinStream(w) + if err != nil { + t.Fatalf("Could not init a BinstremWriter: %s", err) + } + if _, err := bsw.Write([]byte("hello")); err != nil { + t.Fatalf("Could not write chunk to bsw: %s", err) + } + if _, err := bsw.Write([]byte(", ")); err != nil { + t.Fatalf("Could not write chunk to bsw: %s", err) + } + if _, err := bsw.Write([]byte("world!")); err != nil { + t.Fatalf("Could not write chunk to bsw: %s", err) + } + if err := bsw.Close(); err != nil { + t.Fatalf("Could not close bsw: %s", err) + } + + chkerr(t, SendUKey(w, 2), "SendUKey") + chkerr(t, InitList(w), "InitList") + chkerr(t, SendNumber(w, 1), "SendNumber") + chkerr(t, SendNumber(w, 2), "SendNumber") + chkerr(t, SendTerm(w), "SendTerm") + + chkerr(t, SendUKey(w, 3), "SendUKey") + chkerr(t, InitTextKVMap(w), "InitTextKVMap") + chkerr(t, SendTextKey(w, "foo"), "SendTextKey") + chkerr(t, SendBin(w, []byte("bar")), "SendBin") + + chkerr(t, SendTerm(w), "SendTerm") + + chkerr(t, SendUKey(w, 4), "SendUKey") + chkerr(t, SendBool(w, false), "SendBool") + + chkerr(t, SendUKey(w, 5), "SendUKey") + chkerr(t, SendBool(w, true), "SendBool") + + chkerr(t, SendUKey(w, 6), "SendUKey") + chkerr(t, SendByte(w, 10), "SendByte") + + chkerr(t, SendTerm(w), "SendTerm") + + if !bytes.Equal(w.Bytes(), data) { + t.Errorf("Wrong data constructed, got: %v", w.Bytes()) + } +} + +func TestSkipping(t *testing.T) { + skipdata := []byte{ + 0x08, // IdKVMap + 0x09, 0x01, // UKey(1) + 0x06, // List + 0x06, // List + 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Number(1) + 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Number(2) + 0x0b, // Term + 0x06, // List + 0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Number(3) + 0x05, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Number(4) + 0x0b, // Term + 0x0b, // Term + 0x09, 0x02, // UKey(2) + 0x07, // TextKVMap + 0x04, 0x03, 0x00, 0x00, 0x00, 'f', 'o', 'o', // Bin(foo) + 0x0a, // BinStream + 0x05, 0x00, 0x00, 0x00, 'h', 'e', 'l', 'l', 'o', // BinStream chunk (hello) + 0x02, 0x00, 0x00, 0x00, ',', ' ', // BinStream chunk (, ) + 0x06, 0x00, 0x00, 0x00, 'w', 'o', 'r', 'l', 'd', '!', // BinStream chunk (world!) + 0xff, 0xff, 0xff, 0xff, // Terminating BinStream + 0x0b, // Term + 0x0b, // Term + 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // Number(8) + + r := bytes.NewReader(skipdata) + ur := NewSimpleUnitReader(r) + + if err := SkipNext(ur); err != nil { + t.Fatalf("Skipping failed: %s", err) + } + + if ut, data, err := ur.ReadUnit(); (err != nil) || (ut != UTNumber) || (data.(int64) != 8) { + t.Errorf("ReadUnit returned with unexpected data: %s, %v, %s", ut, data, err) + } +} |