]> Cypherpunks.ru repositories - netstring.git/blobdiff - ns_test.go
Refactoring, io.Reader/Writer friendliness, performance optimization
[netstring.git] / ns_test.go
diff --git a/ns_test.go b/ns_test.go
new file mode 100644 (file)
index 0000000..084cd6d
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+netstring -- netstring format serialization library
+Copyright (C) 2015-2020 Sergey Matveev <stargrave@stargrave.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 3 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package netstring
+
+import (
+       "bytes"
+       "io/ioutil"
+       "testing"
+       "testing/quick"
+)
+
+func TestTrivial(t *testing.T) {
+       var buf bytes.Buffer
+       w := NewWriter(&buf)
+       if n, err := w.WriteChunk([]byte{}); err != nil || n != 3 || string(buf.Next(3)) != "0:," {
+               t.FailNow()
+       }
+       if n, err := w.WriteChunk([]byte("foo")); err != nil || n != 6 {
+               t.FailNow()
+       }
+       if n, err := w.WriteChunk([]byte("barz")); err != nil || n != 7 {
+               t.FailNow()
+       }
+       if string(buf.Bytes()) != "3:foo,4:barz," {
+               t.FailNow()
+       }
+       r := NewReader(&buf)
+       if n, err := r.Next(); err != nil || n != 3 {
+               t.FailNow()
+       }
+       if r.Discard() != nil {
+               t.FailNow()
+       }
+       if n, err := r.Next(); err != nil || n != 4 {
+               t.FailNow()
+       }
+       m := make([]byte, 4)
+       if n, err := r.Read(m); err != nil || n != 4 {
+               t.FailNow()
+       }
+       if bytes.Compare(m, []byte("barz")) != 0 {
+               t.FailNow()
+       }
+}
+
+func TestSymmetric(t *testing.T) {
+       var buf bytes.Buffer
+       w := NewWriter(&buf)
+       r := NewReader(&buf)
+       f := func(datum [][]byte) bool {
+               for _, data := range datum {
+                       if n, err := w.WriteChunk(data); err != nil || n <= len(data) {
+                               return false
+                       }
+               }
+               for _, data := range datum {
+                       if n, err := r.Next(); err != nil || n != uint64(len(data)) {
+                               return false
+                       }
+                       got, err := ioutil.ReadAll(r)
+                       if err != nil || bytes.Compare(got, data) != 0 {
+                               return false
+                       }
+               }
+               return true
+       }
+       if err := quick.Check(f, nil); err != nil {
+               t.Error(err)
+       }
+}
+
+func TestErrors(t *testing.T) {
+       b := bytes.NewBufferString("junk")
+       r := NewReader(b)
+       if _, err := r.Next(); err == nil {
+               t.FailNow()
+       }
+
+       b = bytes.NewBufferString("1111111111111111111111:")
+       r = NewReader(b)
+       if _, err := r.Next(); err == nil {
+               t.FailNow()
+       }
+
+       b = bytes.NewBufferString("6foobar")
+       r = NewReader(b)
+       if _, err := r.Next(); err == nil {
+               t.FailNow()
+       }
+
+       data := make([]byte, 1<<10)
+
+       b = bytes.NewBufferString("0:foobar,")
+       r = NewReader(b)
+       if _, err := r.Next(); err != nil {
+               t.FailNow()
+       }
+       if _, err := r.Read(data); err == nil {
+               t.FailNow()
+       }
+
+       b = bytes.NewBufferString("0:foobar")
+       r = NewReader(b)
+       if _, err := r.Next(); err != nil {
+               t.FailNow()
+       }
+       if _, err := r.Read(data); err == nil {
+               t.FailNow()
+       }
+
+       b = bytes.NewBufferString("6:foobar")
+       r = NewReader(b)
+       if _, err := r.Next(); err != nil {
+               t.FailNow()
+       }
+       if _, err := r.Read(data); err == nil {
+               t.FailNow()
+       }
+}
+
+func TestExample(t *testing.T) {
+       var b bytes.Buffer
+       w := NewWriter(&b)
+       if n, err := w.WriteChunk([]byte("hello")); err != nil || n != 8 || b.String() != "5:hello," {
+               t.FailNow()
+       }
+       if n, err := w.WriteSize(6); err != nil || n != 2 {
+               t.FailNow()
+       }
+       if n, err := w.Write([]byte("wor")); err != nil || n != 3 {
+               t.FailNow()
+       }
+       if n, err := w.Write([]byte("ld!")); err != nil || n != 3 || b.String() != "5:hello,6:world!," {
+               t.FailNow()
+       }
+       r := NewReader(&b)
+       if size, err := r.Next(); err != nil || size != 5 {
+               t.FailNow()
+       }
+       if err := r.Discard(); err != nil {
+               t.FailNow()
+       }
+       if size, err := r.Next(); err != nil || size != 6 {
+               t.FailNow()
+       }
+       if data, err := ioutil.ReadAll(r); err != nil || string(data) != "world!" {
+               t.FailNow()
+       }
+}