]> Cypherpunks.ru repositories - netstring.git/blob - ns_test.go
Do not require explicit Read for zero length
[netstring.git] / ns_test.go
1 /*
2 netstring -- netstring format serialization library
3 Copyright (C) 2015-2023 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package netstring
19
20 import (
21         "bytes"
22         "io"
23         "testing"
24         "testing/quick"
25 )
26
27 func TestTrivial(t *testing.T) {
28         var buf bytes.Buffer
29         w := NewWriter(&buf)
30         if n, err := w.WriteChunk([]byte{}); err != nil || n != 3 || string(buf.Next(3)) != "0:," {
31                 t.FailNow()
32         }
33         if n, err := w.WriteChunk([]byte("foo")); err != nil || n != 6 {
34                 t.FailNow()
35         }
36         if n, err := w.WriteChunk([]byte("barz")); err != nil || n != 7 {
37                 t.FailNow()
38         }
39         if buf.String() != "3:foo,4:barz," {
40                 t.FailNow()
41         }
42         r := NewReader(&buf)
43         if n, err := r.Next(); err != nil || n != 3 {
44                 t.FailNow()
45         }
46         if r.Discard() != nil {
47                 t.FailNow()
48         }
49         if n, err := r.Next(); err != nil || n != 4 {
50                 t.FailNow()
51         }
52         m := make([]byte, 4)
53         if n, err := r.Read(m); err != nil || n != 4 {
54                 t.FailNow()
55         }
56         if !bytes.Equal(m, []byte("barz")) {
57                 t.FailNow()
58         }
59 }
60
61 func TestSymmetric(t *testing.T) {
62         var buf bytes.Buffer
63         w := NewWriter(&buf)
64         r := NewReader(&buf)
65         f := func(datum [][]byte) bool {
66                 for _, data := range datum {
67                         if n, err := w.WriteChunk(data); err != nil || n <= len(data) {
68                                 return false
69                         }
70                 }
71                 for _, data := range datum {
72                         if n, err := r.Next(); err != nil || n != uint64(len(data)) {
73                                 return false
74                         }
75                         got, err := io.ReadAll(r)
76                         if err != nil || !bytes.Equal(got, data) {
77                                 return false
78                         }
79                 }
80                 return true
81         }
82         if err := quick.Check(f, nil); err != nil {
83                 t.Error(err)
84         }
85 }
86
87 func TestErrors(t *testing.T) {
88         b := bytes.NewBufferString("junk")
89         r := NewReader(b)
90         if _, err := r.Next(); err == nil {
91                 t.FailNow()
92         }
93
94         b = bytes.NewBufferString("1111111111111111111111:")
95         r = NewReader(b)
96         if _, err := r.Next(); err == nil {
97                 t.FailNow()
98         }
99
100         b = bytes.NewBufferString("6foobar")
101         r = NewReader(b)
102         if _, err := r.Next(); err == nil {
103                 t.FailNow()
104         }
105
106         data := make([]byte, 1<<10)
107
108         b = bytes.NewBufferString("0:foobar,")
109         r = NewReader(b)
110         if _, err := r.Next(); err == nil {
111                 t.FailNow()
112         }
113
114         b = bytes.NewBufferString("6:foobar")
115         r = NewReader(b)
116         if _, err := r.Next(); err != nil {
117                 t.FailNow()
118         }
119         if _, err := r.Read(data); err == nil {
120                 t.FailNow()
121         }
122
123         b = bytes.NewBufferString(":foobar,")
124         r = NewReader(b)
125         if _, err := r.Next(); err == nil {
126                 t.FailNow()
127         }
128
129         b = bytes.NewBufferString("06:foobar,")
130         r = NewReader(b)
131         if _, err := r.Next(); err == nil {
132                 t.FailNow()
133         }
134 }
135
136 func TestExample(t *testing.T) {
137         var b bytes.Buffer
138         w := NewWriter(&b)
139         if n, err := w.WriteChunk([]byte("hello")); err != nil || n != 8 || b.String() != "5:hello," {
140                 t.FailNow()
141         }
142         if n, err := w.WriteSize(6); err != nil || n != 2 {
143                 t.FailNow()
144         }
145         if n, err := w.Write([]byte("wor")); err != nil || n != 3 {
146                 t.FailNow()
147         }
148         if n, err := w.Write([]byte("ld!")); err != nil || n != 3 || b.String() != "5:hello,6:world!," {
149                 t.FailNow()
150         }
151         r := NewReader(&b)
152         if size, err := r.Next(); err != nil || size != 5 {
153                 t.FailNow()
154         }
155         if err := r.Discard(); err != nil {
156                 t.FailNow()
157         }
158         if size, err := r.Next(); err != nil || size != 6 {
159                 t.FailNow()
160         }
161         if data, err := io.ReadAll(r); err != nil || string(data) != "world!" {
162                 t.FailNow()
163         }
164 }