// netstring -- netstring format serialization library // Copyright (C) 2015-2024 Sergey Matveev // // 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 . package netstring import ( "bytes" "io" "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 buf.String() != "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.Equal(m, []byte("barz")) { 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 := io.ReadAll(r) if err != nil || !bytes.Equal(got, data) { 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() } 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() } b = bytes.NewBufferString(":foobar,") r = NewReader(b) if _, err := r.Next(); err == nil { t.FailNow() } b = bytes.NewBufferString("06:foobar,") r = NewReader(b) if _, err := r.Next(); 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 := io.ReadAll(r); err != nil || string(data) != "world!" { t.FailNow() } }