1package unsnap
2
3import (
4	"bytes"
5	"fmt"
6	"io"
7	"testing"
8
9	cv "github.com/glycerine/goconvey/convey"
10)
11
12func TestRingBufReadWrite(t *testing.T) {
13	b := NewFixedSizeRingBuf(5)
14
15	data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
16
17	cv.Convey("Given a FixedSizeRingBuf of size 5", t, func() {
18		cv.Convey("Write(), Bytes(), and Read() should put and get bytes", func() {
19			n, err := b.Write(data[0:5])
20			cv.So(n, cv.ShouldEqual, 5)
21			cv.So(err, cv.ShouldEqual, nil)
22			cv.So(b.Readable, cv.ShouldEqual, 5)
23			if n != 5 {
24				fmt.Printf("should have been able to write 5 bytes.\n")
25			}
26			if err != nil {
27				panic(err)
28			}
29			cv.So(b.Bytes(), cv.ShouldResemble, data[0:5])
30
31			sink := make([]byte, 3)
32			n, err = b.Read(sink)
33			cv.So(n, cv.ShouldEqual, 3)
34			cv.So(b.Bytes(), cv.ShouldResemble, data[3:5])
35			cv.So(sink, cv.ShouldResemble, data[0:3])
36		})
37
38		cv.Convey("Write() more than 5 should give back ErrShortWrite", func() {
39			b.Reset()
40			cv.So(b.Readable, cv.ShouldEqual, 0)
41			n, err := b.Write(data[0:10])
42			cv.So(n, cv.ShouldEqual, 5)
43			cv.So(err, cv.ShouldEqual, io.ErrShortWrite)
44			cv.So(b.Readable, cv.ShouldEqual, 5)
45			if n != 5 {
46				fmt.Printf("should have been able to write 5 bytes.\n")
47			}
48			cv.So(b.Bytes(), cv.ShouldResemble, data[0:5])
49
50			sink := make([]byte, 3)
51			n, err = b.Read(sink)
52			cv.So(n, cv.ShouldEqual, 3)
53			cv.So(b.Bytes(), cv.ShouldResemble, data[3:5])
54			cv.So(sink, cv.ShouldResemble, data[0:3])
55		})
56
57		cv.Convey("we should be able to wrap data and then get it back in Bytes()", func() {
58			b.Reset()
59
60			n, err := b.Write(data[0:3])
61			cv.So(n, cv.ShouldEqual, 3)
62			cv.So(err, cv.ShouldEqual, nil)
63
64			sink := make([]byte, 3)
65			n, err = b.Read(sink) // put b.beg at 3
66			cv.So(n, cv.ShouldEqual, 3)
67			cv.So(err, cv.ShouldEqual, nil)
68			cv.So(b.Readable, cv.ShouldEqual, 0)
69
70			n, err = b.Write(data[3:8]) // wrap 3 bytes around to the front
71			cv.So(n, cv.ShouldEqual, 5)
72			cv.So(err, cv.ShouldEqual, nil)
73
74			by := b.Bytes()
75			cv.So(by, cv.ShouldResemble, data[3:8]) // but still get them back from the ping-pong buffering
76
77		})
78
79		cv.Convey("FixedSizeRingBuf::WriteTo() should work with wrapped data", func() {
80			b.Reset()
81
82			n, err := b.Write(data[0:3])
83			cv.So(n, cv.ShouldEqual, 3)
84			cv.So(err, cv.ShouldEqual, nil)
85
86			sink := make([]byte, 3)
87			n, err = b.Read(sink) // put b.beg at 3
88			cv.So(n, cv.ShouldEqual, 3)
89			cv.So(err, cv.ShouldEqual, nil)
90			cv.So(b.Readable, cv.ShouldEqual, 0)
91
92			n, err = b.Write(data[3:8]) // wrap 3 bytes around to the front
93
94			var bb bytes.Buffer
95			m, err := b.WriteTo(&bb)
96
97			cv.So(m, cv.ShouldEqual, 5)
98			cv.So(err, cv.ShouldEqual, nil)
99
100			by := bb.Bytes()
101			cv.So(by, cv.ShouldResemble, data[3:8]) // but still get them back from the ping-pong buffering
102
103		})
104
105		cv.Convey("FixedSizeRingBuf::ReadFrom() should work with wrapped data", func() {
106			b.Reset()
107			var bb bytes.Buffer
108			n, err := b.ReadFrom(&bb)
109			cv.So(n, cv.ShouldEqual, 0)
110			cv.So(err, cv.ShouldEqual, nil)
111
112			// write 4, then read 4 bytes
113			m, err := b.Write(data[0:4])
114			cv.So(m, cv.ShouldEqual, 4)
115			cv.So(err, cv.ShouldEqual, nil)
116
117			sink := make([]byte, 4)
118			k, err := b.Read(sink) // put b.beg at 4
119			cv.So(k, cv.ShouldEqual, 4)
120			cv.So(err, cv.ShouldEqual, nil)
121			cv.So(b.Readable, cv.ShouldEqual, 0)
122			cv.So(b.Beg, cv.ShouldEqual, 4)
123
124			bbread := bytes.NewBuffer(data[4:9])
125			n, err = b.ReadFrom(bbread) // wrap 4 bytes around to the front, 5 bytes total.
126
127			by := b.Bytes()
128			cv.So(by, cv.ShouldResemble, data[4:9]) // but still get them back continguous from the ping-pong buffering
129
130		})
131
132		cv.Convey("FixedSizeRingBuf::GetEndmostWritableSlice() should return the slice size we expect.", func() {
133			b.Reset()
134			var bb bytes.Buffer
135			n, err := b.ReadFrom(&bb)
136			cv.So(n, cv.ShouldEqual, 0)
137			cv.So(err, cv.ShouldEqual, nil)
138			cv.So(len(b.GetEndmostWritableSlice()), cv.ShouldEqual, 5)
139
140			// write 4, then read 4 bytes
141			m, err := b.Write(data[0:4])
142			cv.So(m, cv.ShouldEqual, 4)
143			cv.So(err, cv.ShouldEqual, nil)
144			cv.So(len(b.GetEndmostWritableSlice()), cv.ShouldEqual, 1)
145
146			sink := make([]byte, 4)
147			k, err := b.Read(sink) // put b.beg at 4
148			cv.So(k, cv.ShouldEqual, 4)
149			cv.So(err, cv.ShouldEqual, nil)
150			cv.So(b.Readable, cv.ShouldEqual, 0)
151			cv.So(b.Beg, cv.ShouldEqual, 4)
152
153			bbread := bytes.NewBuffer(data[4:9])
154			n, err = b.ReadFrom(bbread) // wrap 4 bytes around to the front, 5 bytes total.
155
156			by := b.Bytes()
157			cv.So(by, cv.ShouldResemble, data[4:9]) // but still get them back continguous from the ping-pong buffering
158
159			cv.So(len(b.GetEndmostWritableSlice()), cv.ShouldEqual, 0)
160		})
161
162	})
163
164}
165