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