1package fwd 2 3import ( 4 "bytes" 5 "io" 6 "math/rand" 7 "testing" 8) 9 10type chunkedWriter struct { 11 w *Writer 12} 13 14// writes 'p' in randomly-sized chunks 15func (c chunkedWriter) Write(p []byte) (int, error) { 16 l := len(p) 17 n := 0 18 for n < l { 19 amt := max(rand.Intn(l-n), 1) // number of bytes to write; at least 1 20 nn, err := c.w.Write(p[n : n+amt]) // 21 n += nn 22 if err == nil && nn < amt { 23 err = io.ErrShortWrite 24 } 25 if err != nil { 26 return n, err 27 } 28 } 29 return n, nil 30} 31 32// analogous to Write(), but w/ str 33func (c chunkedWriter) WriteString(s string) (int, error) { 34 l := len(s) 35 n := 0 36 for n < l { 37 amt := max(rand.Intn(l-n), 1) // number of bytes to write; at least 1 38 nn, err := c.w.WriteString(s[n : n+amt]) // 39 n += nn 40 if err == nil && nn < amt { 41 err = io.ErrShortWrite 42 } 43 if err != nil { 44 return n, err 45 } 46 } 47 return n, nil 48} 49 50// writes via random calls to Next() 51type nextWriter struct { 52 wr *Writer 53} 54 55func (c nextWriter) Write(p []byte) (int, error) { 56 l := len(p) 57 n := 0 58 for n < l { 59 amt := max(rand.Intn(l-n), 1) // at least 1 byte 60 fwd, err := c.wr.Next(amt) // get next (amt) bytes 61 if err != nil { 62 63 // this may happen occasionally 64 if err == io.ErrShortBuffer { 65 if cap(c.wr.buf) >= amt { 66 panic("bad io.ErrShortBuffer") 67 } 68 continue 69 } 70 71 return n, err 72 } 73 if len(fwd) != amt { 74 panic("bad Next() len") 75 } 76 n += copy(fwd, p[n:]) 77 } 78 return n, nil 79} 80 81func TestWrite(t *testing.T) { 82 nbts := 4096 83 bts := randomBts(nbts) 84 var buf bytes.Buffer 85 wr := NewWriterSize(&buf, 512) 86 87 if wr.BufferSize() != 512 { 88 t.Fatalf("expected BufferSize() to be %d; found %d", 512, wr.BufferSize()) 89 } 90 91 cwr := chunkedWriter{wr} 92 nb, err := cwr.Write(bts) 93 if err != nil { 94 t.Fatal(err) 95 } 96 if nb != nbts { 97 t.Fatalf("expected to write %d bytes; wrote %d bytes", nbts, nb) 98 } 99 err = wr.Flush() 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 if wr.Buffered() != 0 { 105 t.Fatalf("expected 0 buffered bytes; found %d", wr.Buffered()) 106 } 107 108 if buf.Len() != nbts { 109 t.Fatalf("wrote %d bytes, but buffer is %d bytes long", nbts, buf.Len()) 110 } 111 if !bytes.Equal(bts, buf.Bytes()) { 112 t.Fatal("buf.Bytes() is not the same as the input bytes") 113 } 114} 115 116func TestWriteString(t *testing.T) { 117 nbts := 3998 118 str := string(randomBts(nbts)) 119 var buf bytes.Buffer 120 wr := NewWriterSize(&buf, 1137) 121 122 if wr.BufferSize() != 1137 { 123 t.Fatalf("expected BufferSize() to return %d; returned %d", 1137, wr.BufferSize()) 124 } 125 126 cwr := chunkedWriter{wr} 127 nb, err := cwr.WriteString(str) 128 if err != nil { 129 t.Fatal(err) 130 } 131 if nb != nbts { 132 t.Fatalf("expected to write %d bytes; wrote %d bytes", nbts, nb) 133 } 134 135 err = wr.Flush() 136 if err != nil { 137 t.Fatal(err) 138 } 139 140 if wr.Buffered() != 0 { 141 t.Fatalf("expected 0 buffered bytes; found %d", wr.Buffered()) 142 } 143 144 if buf.Len() != nbts { 145 t.Fatalf("wrote %d bytes, buf buffer is %d bytes long", nbts, buf.Len()) 146 } 147 if buf.String() != str { 148 t.Fatal("buf.String() is not the same as input string") 149 } 150} 151 152func TestWriteByte(t *testing.T) { 153 nbts := 3200 154 bts := randomBts(nbts) 155 var buf bytes.Buffer 156 wr := NewWriter(&buf) 157 158 if wr.BufferSize() != DefaultWriterSize { 159 t.Fatalf("expected BufferSize() to return %d; returned %d", DefaultWriterSize, wr.BufferSize()) 160 } 161 162 // write byte-by-byte 163 for _, b := range bts { 164 if err := wr.WriteByte(b); err != nil { 165 t.Fatal(err) 166 } 167 } 168 169 err := wr.Flush() 170 if err != nil { 171 t.Fatal(err) 172 } 173 174 if buf.Len() != nbts { 175 t.Fatalf("expected buf.Len() to be %d; got %d", nbts, buf.Len()) 176 } 177 178 if !bytes.Equal(buf.Bytes(), bts) { 179 t.Fatal("buf.Bytes() and input are not equal") 180 } 181} 182 183func TestWriterNext(t *testing.T) { 184 nbts := 1871 185 bts := randomBts(nbts) 186 var buf bytes.Buffer 187 wr := NewWriterSize(&buf, 500) 188 nwr := nextWriter{wr} 189 190 nb, err := nwr.Write(bts) 191 if err != nil { 192 t.Fatal(err) 193 } 194 195 if nb != nbts { 196 t.Fatalf("expected to write %d bytes; wrote %d", nbts, nb) 197 } 198 199 err = wr.Flush() 200 if err != nil { 201 t.Fatal(err) 202 } 203 204 if buf.Len() != nbts { 205 t.Fatalf("expected buf.Len() to be %d; got %d", nbts, buf.Len()) 206 } 207 208 if !bytes.Equal(buf.Bytes(), bts) { 209 t.Fatal("buf.Bytes() and input are not equal") 210 } 211} 212 213func TestReadFrom(t *testing.T) { 214 nbts := 2139 215 bts := randomBts(nbts) 216 var buf bytes.Buffer 217 wr := NewWriterSize(&buf, 987) 218 219 rd := partialReader{bytes.NewReader(bts)} 220 221 nb, err := wr.ReadFrom(rd) 222 if err != nil { 223 t.Fatal(err) 224 } 225 if nb != int64(nbts) { 226 t.Fatalf("expeted to write %d bytes; wrote %d", nbts, nb) 227 } 228 err = wr.Flush() 229 if err != nil { 230 t.Fatal(err) 231 } 232 if buf.Len() != nbts { 233 t.Fatalf("expected buf.Len() to be %d; got %d", nbts, buf.Len()) 234 } 235 if !bytes.Equal(buf.Bytes(), bts) { 236 t.Fatal("buf.Bytes() and input are not equal") 237 } 238 239} 240