github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/bytes/reader_test.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package bytes_test 6 7 import ( 8 . "bytes" 9 "fmt" 10 "io" 11 "io/ioutil" 12 "sync" 13 "testing" 14 ) 15 16 func TestReader(t *testing.T) { 17 r := NewReader([]byte("0123456789")) 18 tests := []struct { 19 off int64 20 seek int 21 n int 22 want string 23 wantpos int64 24 readerr error 25 seekerr string 26 }{ 27 {seek: io.SeekStart, off: 0, n: 20, want: "0123456789"}, 28 {seek: io.SeekStart, off: 1, n: 1, want: "1"}, 29 {seek: io.SeekCurrent, off: 1, wantpos: 3, n: 2, want: "34"}, 30 {seek: io.SeekStart, off: -1, seekerr: "bytes.Reader.Seek: negative position"}, 31 {seek: io.SeekStart, off: 1 << 33, wantpos: 1 << 33, readerr: io.EOF}, 32 {seek: io.SeekCurrent, off: 1, wantpos: 1<<33 + 1, readerr: io.EOF}, 33 {seek: io.SeekStart, n: 5, want: "01234"}, 34 {seek: io.SeekCurrent, n: 5, want: "56789"}, 35 {seek: io.SeekEnd, off: -1, n: 1, wantpos: 9, want: "9"}, 36 } 37 38 for i, tt := range tests { 39 pos, err := r.Seek(tt.off, tt.seek) 40 if err == nil && tt.seekerr != "" { 41 t.Errorf("%d. want seek error %q", i, tt.seekerr) 42 continue 43 } 44 if err != nil && err.Error() != tt.seekerr { 45 t.Errorf("%d. seek error = %q; want %q", i, err.Error(), tt.seekerr) 46 continue 47 } 48 if tt.wantpos != 0 && tt.wantpos != pos { 49 t.Errorf("%d. pos = %d, want %d", i, pos, tt.wantpos) 50 } 51 buf := make([]byte, tt.n) 52 n, err := r.Read(buf) 53 if err != tt.readerr { 54 t.Errorf("%d. read = %v; want %v", i, err, tt.readerr) 55 continue 56 } 57 got := string(buf[:n]) 58 if got != tt.want { 59 t.Errorf("%d. got %q; want %q", i, got, tt.want) 60 } 61 } 62 } 63 64 func TestReadAfterBigSeek(t *testing.T) { 65 r := NewReader([]byte("0123456789")) 66 if _, err := r.Seek(1<<31+5, io.SeekStart); err != nil { 67 t.Fatal(err) 68 } 69 if n, err := r.Read(make([]byte, 10)); n != 0 || err != io.EOF { 70 t.Errorf("Read = %d, %v; want 0, EOF", n, err) 71 } 72 } 73 74 func TestReaderAt(t *testing.T) { 75 r := NewReader([]byte("0123456789")) 76 tests := []struct { 77 off int64 78 n int 79 want string 80 wanterr interface{} 81 }{ 82 {0, 10, "0123456789", nil}, 83 {1, 10, "123456789", io.EOF}, 84 {1, 9, "123456789", nil}, 85 {11, 10, "", io.EOF}, 86 {0, 0, "", nil}, 87 {-1, 0, "", "bytes.Reader.ReadAt: negative offset"}, 88 } 89 for i, tt := range tests { 90 b := make([]byte, tt.n) 91 rn, err := r.ReadAt(b, tt.off) 92 got := string(b[:rn]) 93 if got != tt.want { 94 t.Errorf("%d. got %q; want %q", i, got, tt.want) 95 } 96 if fmt.Sprintf("%v", err) != fmt.Sprintf("%v", tt.wanterr) { 97 t.Errorf("%d. got error = %v; want %v", i, err, tt.wanterr) 98 } 99 } 100 } 101 102 func TestReaderAtConcurrent(t *testing.T) { 103 // Test for the race detector, to verify ReadAt doesn't mutate 104 // any state. 105 r := NewReader([]byte("0123456789")) 106 var wg sync.WaitGroup 107 for i := 0; i < 5; i++ { 108 wg.Add(1) 109 go func(i int) { 110 defer wg.Done() 111 var buf [1]byte 112 r.ReadAt(buf[:], int64(i)) 113 }(i) 114 } 115 wg.Wait() 116 } 117 118 func TestEmptyReaderConcurrent(t *testing.T) { 119 // Test for the race detector, to verify a Read that doesn't yield any bytes 120 // is okay to use from multiple goroutines. This was our historic behavior. 121 // See golang.org/issue/7856 122 r := NewReader([]byte{}) 123 var wg sync.WaitGroup 124 for i := 0; i < 5; i++ { 125 wg.Add(2) 126 go func() { 127 defer wg.Done() 128 var buf [1]byte 129 r.Read(buf[:]) 130 }() 131 go func() { 132 defer wg.Done() 133 r.Read(nil) 134 }() 135 } 136 wg.Wait() 137 } 138 139 func TestReaderWriteTo(t *testing.T) { 140 for i := 0; i < 30; i += 3 { 141 var l int 142 if i > 0 { 143 l = len(data) / i 144 } 145 s := data[:l] 146 r := NewReader(testBytes[:l]) 147 var b Buffer 148 n, err := r.WriteTo(&b) 149 if expect := int64(len(s)); n != expect { 150 t.Errorf("got %v; want %v", n, expect) 151 } 152 if err != nil { 153 t.Errorf("for length %d: got error = %v; want nil", l, err) 154 } 155 if b.String() != s { 156 t.Errorf("got string %q; want %q", b.String(), s) 157 } 158 if r.Len() != 0 { 159 t.Errorf("reader contains %v bytes; want 0", r.Len()) 160 } 161 } 162 } 163 164 func TestReaderLen(t *testing.T) { 165 const data = "hello world" 166 r := NewReader([]byte(data)) 167 if got, want := r.Len(), 11; got != want { 168 t.Errorf("r.Len(): got %d, want %d", got, want) 169 } 170 if n, err := r.Read(make([]byte, 10)); err != nil || n != 10 { 171 t.Errorf("Read failed: read %d %v", n, err) 172 } 173 if got, want := r.Len(), 1; got != want { 174 t.Errorf("r.Len(): got %d, want %d", got, want) 175 } 176 if n, err := r.Read(make([]byte, 1)); err != nil || n != 1 { 177 t.Errorf("Read failed: read %d %v; want 1, nil", n, err) 178 } 179 if got, want := r.Len(), 0; got != want { 180 t.Errorf("r.Len(): got %d, want %d", got, want) 181 } 182 } 183 184 var UnreadRuneErrorTests = []struct { 185 name string 186 f func(*Reader) 187 }{ 188 {"Read", func(r *Reader) { r.Read([]byte{0}) }}, 189 {"ReadByte", func(r *Reader) { r.ReadByte() }}, 190 {"UnreadRune", func(r *Reader) { r.UnreadRune() }}, 191 {"Seek", func(r *Reader) { r.Seek(0, io.SeekCurrent) }}, 192 {"WriteTo", func(r *Reader) { r.WriteTo(&Buffer{}) }}, 193 } 194 195 func TestUnreadRuneError(t *testing.T) { 196 for _, tt := range UnreadRuneErrorTests { 197 reader := NewReader([]byte("0123456789")) 198 if _, _, err := reader.ReadRune(); err != nil { 199 // should not happen 200 t.Fatal(err) 201 } 202 tt.f(reader) 203 err := reader.UnreadRune() 204 if err == nil { 205 t.Errorf("Unreading after %s: expected error", tt.name) 206 } 207 } 208 } 209 210 func TestReaderDoubleUnreadRune(t *testing.T) { 211 buf := NewBuffer([]byte("groucho")) 212 if _, _, err := buf.ReadRune(); err != nil { 213 // should not happen 214 t.Fatal(err) 215 } 216 if err := buf.UnreadByte(); err != nil { 217 // should not happen 218 t.Fatal(err) 219 } 220 if err := buf.UnreadByte(); err == nil { 221 t.Fatal("UnreadByte: expected error, got nil") 222 } 223 } 224 225 // verify that copying from an empty reader always has the same results, 226 // regardless of the presence of a WriteTo method. 227 func TestReaderCopyNothing(t *testing.T) { 228 type nErr struct { 229 n int64 230 err error 231 } 232 type justReader struct { 233 io.Reader 234 } 235 type justWriter struct { 236 io.Writer 237 } 238 discard := justWriter{ioutil.Discard} // hide ReadFrom 239 240 var with, withOut nErr 241 with.n, with.err = io.Copy(discard, NewReader(nil)) 242 withOut.n, withOut.err = io.Copy(discard, justReader{NewReader(nil)}) 243 if with != withOut { 244 t.Errorf("behavior differs: with = %#v; without: %#v", with, withOut) 245 } 246 } 247 248 // tests that Len is affected by reads, but Size is not. 249 func TestReaderLenSize(t *testing.T) { 250 r := NewReader([]byte("abc")) 251 io.CopyN(ioutil.Discard, r, 1) 252 if r.Len() != 2 { 253 t.Errorf("Len = %d; want 2", r.Len()) 254 } 255 if r.Size() != 3 { 256 t.Errorf("Size = %d; want 3", r.Size()) 257 } 258 } 259 260 func TestReaderReset(t *testing.T) { 261 r := NewReader([]byte("世界")) 262 if _, _, err := r.ReadRune(); err != nil { 263 t.Errorf("ReadRune: unexpected error: %v", err) 264 } 265 266 const want = "abcdef" 267 r.Reset([]byte(want)) 268 if err := r.UnreadRune(); err == nil { 269 t.Errorf("UnreadRune: expected error, got nil") 270 } 271 buf, err := ioutil.ReadAll(r) 272 if err != nil { 273 t.Errorf("ReadAll: unexpected error: %v", err) 274 } 275 if got := string(buf); got != want { 276 t.Errorf("ReadAll: got %q, want %q", got, want) 277 } 278 }