summaryrefslogtreecommitdiff
path: root/binproto_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'binproto_test.go')
-rw-r--r--binproto_test.go262
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)
+ }
+}