Source file
src/io/io_test.go
1
2
3
4
5 package io_test
6
7 import (
8 "bytes"
9 "errors"
10 "fmt"
11 . "io"
12 "os"
13 "strings"
14 "sync"
15 "sync/atomic"
16 "testing"
17 )
18
19
20 type Buffer struct {
21 bytes.Buffer
22 ReaderFrom
23 WriterTo
24 }
25
26
27
28 func TestCopy(t *testing.T) {
29 rb := new(Buffer)
30 wb := new(Buffer)
31 rb.WriteString("hello, world.")
32 Copy(wb, rb)
33 if wb.String() != "hello, world." {
34 t.Errorf("Copy did not work properly")
35 }
36 }
37
38 func TestCopyNegative(t *testing.T) {
39 rb := new(Buffer)
40 wb := new(Buffer)
41 rb.WriteString("hello")
42 Copy(wb, &LimitedReader{R: rb, N: -1})
43 if wb.String() != "" {
44 t.Errorf("Copy on LimitedReader with N<0 copied data")
45 }
46
47 CopyN(wb, rb, -1)
48 if wb.String() != "" {
49 t.Errorf("CopyN with N<0 copied data")
50 }
51 }
52
53 func TestCopyBuffer(t *testing.T) {
54 rb := new(Buffer)
55 wb := new(Buffer)
56 rb.WriteString("hello, world.")
57 CopyBuffer(wb, rb, make([]byte, 1))
58 if wb.String() != "hello, world." {
59 t.Errorf("CopyBuffer did not work properly")
60 }
61 }
62
63 func TestCopyBufferNil(t *testing.T) {
64 rb := new(Buffer)
65 wb := new(Buffer)
66 rb.WriteString("hello, world.")
67 CopyBuffer(wb, rb, nil)
68 if wb.String() != "hello, world." {
69 t.Errorf("CopyBuffer did not work properly")
70 }
71 }
72
73 func TestCopyReadFrom(t *testing.T) {
74 rb := new(Buffer)
75 wb := new(bytes.Buffer)
76 rb.WriteString("hello, world.")
77 Copy(wb, rb)
78 if wb.String() != "hello, world." {
79 t.Errorf("Copy did not work properly")
80 }
81 }
82
83 func TestCopyWriteTo(t *testing.T) {
84 rb := new(bytes.Buffer)
85 wb := new(Buffer)
86 rb.WriteString("hello, world.")
87 Copy(wb, rb)
88 if wb.String() != "hello, world." {
89 t.Errorf("Copy did not work properly")
90 }
91 }
92
93
94 type writeToChecker struct {
95 bytes.Buffer
96 writeToCalled bool
97 }
98
99 func (wt *writeToChecker) WriteTo(w Writer) (int64, error) {
100 wt.writeToCalled = true
101 return wt.Buffer.WriteTo(w)
102 }
103
104
105
106
107 func TestCopyPriority(t *testing.T) {
108 rb := new(writeToChecker)
109 wb := new(bytes.Buffer)
110 rb.WriteString("hello, world.")
111 Copy(wb, rb)
112 if wb.String() != "hello, world." {
113 t.Errorf("Copy did not work properly")
114 } else if !rb.writeToCalled {
115 t.Errorf("WriteTo was not prioritized over ReadFrom")
116 }
117 }
118
119 type zeroErrReader struct {
120 err error
121 }
122
123 func (r zeroErrReader) Read(p []byte) (int, error) {
124 return copy(p, []byte{0}), r.err
125 }
126
127 type errWriter struct {
128 err error
129 }
130
131 func (w errWriter) Write([]byte) (int, error) {
132 return 0, w.err
133 }
134
135
136
137
138 func TestCopyReadErrWriteErr(t *testing.T) {
139 er, ew := errors.New("readError"), errors.New("writeError")
140 r, w := zeroErrReader{err: er}, errWriter{err: ew}
141 n, err := Copy(w, r)
142 if n != 0 || err != ew {
143 t.Errorf("Copy(zeroErrReader, errWriter) = %d, %v; want 0, writeError", n, err)
144 }
145 }
146
147 func TestCopyN(t *testing.T) {
148 rb := new(Buffer)
149 wb := new(Buffer)
150 rb.WriteString("hello, world.")
151 CopyN(wb, rb, 5)
152 if wb.String() != "hello" {
153 t.Errorf("CopyN did not work properly")
154 }
155 }
156
157 func TestCopyNReadFrom(t *testing.T) {
158 rb := new(Buffer)
159 wb := new(bytes.Buffer)
160 rb.WriteString("hello")
161 CopyN(wb, rb, 5)
162 if wb.String() != "hello" {
163 t.Errorf("CopyN did not work properly")
164 }
165 }
166
167 func TestCopyNWriteTo(t *testing.T) {
168 rb := new(bytes.Buffer)
169 wb := new(Buffer)
170 rb.WriteString("hello, world.")
171 CopyN(wb, rb, 5)
172 if wb.String() != "hello" {
173 t.Errorf("CopyN did not work properly")
174 }
175 }
176
177 func BenchmarkCopyNSmall(b *testing.B) {
178 bs := bytes.Repeat([]byte{0}, 512+1)
179 rd := bytes.NewReader(bs)
180 buf := new(Buffer)
181 b.ResetTimer()
182
183 for i := 0; i < b.N; i++ {
184 CopyN(buf, rd, 512)
185 rd.Reset(bs)
186 }
187 }
188
189 func BenchmarkCopyNLarge(b *testing.B) {
190 bs := bytes.Repeat([]byte{0}, (32*1024)+1)
191 rd := bytes.NewReader(bs)
192 buf := new(Buffer)
193 b.ResetTimer()
194
195 for i := 0; i < b.N; i++ {
196 CopyN(buf, rd, 32*1024)
197 rd.Reset(bs)
198 }
199 }
200
201 type noReadFrom struct {
202 w Writer
203 }
204
205 func (w *noReadFrom) Write(p []byte) (n int, err error) {
206 return w.w.Write(p)
207 }
208
209 type wantedAndErrReader struct{}
210
211 func (wantedAndErrReader) Read(p []byte) (int, error) {
212 return len(p), errors.New("wantedAndErrReader error")
213 }
214
215 func TestCopyNEOF(t *testing.T) {
216
217
218
219 b := new(bytes.Buffer)
220
221 n, err := CopyN(&noReadFrom{b}, strings.NewReader("foo"), 3)
222 if n != 3 || err != nil {
223 t.Errorf("CopyN(noReadFrom, foo, 3) = %d, %v; want 3, nil", n, err)
224 }
225
226 n, err = CopyN(&noReadFrom{b}, strings.NewReader("foo"), 4)
227 if n != 3 || err != EOF {
228 t.Errorf("CopyN(noReadFrom, foo, 4) = %d, %v; want 3, EOF", n, err)
229 }
230
231 n, err = CopyN(b, strings.NewReader("foo"), 3)
232 if n != 3 || err != nil {
233 t.Errorf("CopyN(bytes.Buffer, foo, 3) = %d, %v; want 3, nil", n, err)
234 }
235
236 n, err = CopyN(b, strings.NewReader("foo"), 4)
237 if n != 3 || err != EOF {
238 t.Errorf("CopyN(bytes.Buffer, foo, 4) = %d, %v; want 3, EOF", n, err)
239 }
240
241 n, err = CopyN(b, wantedAndErrReader{}, 5)
242 if n != 5 || err != nil {
243 t.Errorf("CopyN(bytes.Buffer, wantedAndErrReader, 5) = %d, %v; want 5, nil", n, err)
244 }
245
246 n, err = CopyN(&noReadFrom{b}, wantedAndErrReader{}, 5)
247 if n != 5 || err != nil {
248 t.Errorf("CopyN(noReadFrom, wantedAndErrReader, 5) = %d, %v; want 5, nil", n, err)
249 }
250 }
251
252 func TestReadAtLeast(t *testing.T) {
253 var rb bytes.Buffer
254 testReadAtLeast(t, &rb)
255 }
256
257
258
259 type dataAndErrorBuffer struct {
260 err error
261 bytes.Buffer
262 }
263
264 func (r *dataAndErrorBuffer) Read(p []byte) (n int, err error) {
265 n, err = r.Buffer.Read(p)
266 if n > 0 && r.Buffer.Len() == 0 && err == nil {
267 err = r.err
268 }
269 return
270 }
271
272 func TestReadAtLeastWithDataAndEOF(t *testing.T) {
273 var rb dataAndErrorBuffer
274 rb.err = EOF
275 testReadAtLeast(t, &rb)
276 }
277
278 func TestReadAtLeastWithDataAndError(t *testing.T) {
279 var rb dataAndErrorBuffer
280 rb.err = fmt.Errorf("fake error")
281 testReadAtLeast(t, &rb)
282 }
283
284 func testReadAtLeast(t *testing.T, rb ReadWriter) {
285 rb.Write([]byte("0123"))
286 buf := make([]byte, 2)
287 n, err := ReadAtLeast(rb, buf, 2)
288 if err != nil {
289 t.Error(err)
290 }
291 if n != 2 {
292 t.Errorf("expected to have read 2 bytes, got %v", n)
293 }
294 n, err = ReadAtLeast(rb, buf, 4)
295 if err != ErrShortBuffer {
296 t.Errorf("expected ErrShortBuffer got %v", err)
297 }
298 if n != 0 {
299 t.Errorf("expected to have read 0 bytes, got %v", n)
300 }
301 n, err = ReadAtLeast(rb, buf, 1)
302 if err != nil {
303 t.Error(err)
304 }
305 if n != 2 {
306 t.Errorf("expected to have read 2 bytes, got %v", n)
307 }
308 n, err = ReadAtLeast(rb, buf, 2)
309 if err != EOF {
310 t.Errorf("expected EOF, got %v", err)
311 }
312 if n != 0 {
313 t.Errorf("expected to have read 0 bytes, got %v", n)
314 }
315 rb.Write([]byte("4"))
316 n, err = ReadAtLeast(rb, buf, 2)
317 want := ErrUnexpectedEOF
318 if rb, ok := rb.(*dataAndErrorBuffer); ok && rb.err != EOF {
319 want = rb.err
320 }
321 if err != want {
322 t.Errorf("expected %v, got %v", want, err)
323 }
324 if n != 1 {
325 t.Errorf("expected to have read 1 bytes, got %v", n)
326 }
327 }
328
329 func TestTeeReader(t *testing.T) {
330 src := []byte("hello, world")
331 dst := make([]byte, len(src))
332 rb := bytes.NewBuffer(src)
333 wb := new(bytes.Buffer)
334 r := TeeReader(rb, wb)
335 if n, err := ReadFull(r, dst); err != nil || n != len(src) {
336 t.Fatalf("ReadFull(r, dst) = %d, %v; want %d, nil", n, err, len(src))
337 }
338 if !bytes.Equal(dst, src) {
339 t.Errorf("bytes read = %q want %q", dst, src)
340 }
341 if !bytes.Equal(wb.Bytes(), src) {
342 t.Errorf("bytes written = %q want %q", wb.Bytes(), src)
343 }
344 if n, err := r.Read(dst); n != 0 || err != EOF {
345 t.Errorf("r.Read at EOF = %d, %v want 0, EOF", n, err)
346 }
347 rb = bytes.NewBuffer(src)
348 pr, pw := Pipe()
349 pr.Close()
350 r = TeeReader(rb, pw)
351 if n, err := ReadFull(r, dst); n != 0 || err != ErrClosedPipe {
352 t.Errorf("closed tee: ReadFull(r, dst) = %d, %v; want 0, EPIPE", n, err)
353 }
354 }
355
356 func TestSectionReader_ReadAt(t *testing.T) {
357 dat := "a long sample data, 1234567890"
358 tests := []struct {
359 data string
360 off int
361 n int
362 bufLen int
363 at int
364 exp string
365 err error
366 }{
367 {data: "", off: 0, n: 10, bufLen: 2, at: 0, exp: "", err: EOF},
368 {data: dat, off: 0, n: len(dat), bufLen: 0, at: 0, exp: "", err: nil},
369 {data: dat, off: len(dat), n: 1, bufLen: 1, at: 0, exp: "", err: EOF},
370 {data: dat, off: 0, n: len(dat) + 2, bufLen: len(dat), at: 0, exp: dat, err: nil},
371 {data: dat, off: 0, n: len(dat), bufLen: len(dat) / 2, at: 0, exp: dat[:len(dat)/2], err: nil},
372 {data: dat, off: 0, n: len(dat), bufLen: len(dat), at: 0, exp: dat, err: nil},
373 {data: dat, off: 0, n: len(dat), bufLen: len(dat) / 2, at: 2, exp: dat[2 : 2+len(dat)/2], err: nil},
374 {data: dat, off: 3, n: len(dat), bufLen: len(dat) / 2, at: 2, exp: dat[5 : 5+len(dat)/2], err: nil},
375 {data: dat, off: 3, n: len(dat) / 2, bufLen: len(dat)/2 - 2, at: 2, exp: dat[5 : 5+len(dat)/2-2], err: nil},
376 {data: dat, off: 3, n: len(dat) / 2, bufLen: len(dat)/2 + 2, at: 2, exp: dat[5 : 5+len(dat)/2-2], err: EOF},
377 {data: dat, off: 0, n: 0, bufLen: 0, at: -1, exp: "", err: EOF},
378 {data: dat, off: 0, n: 0, bufLen: 0, at: 1, exp: "", err: EOF},
379 }
380 for i, tt := range tests {
381 r := strings.NewReader(tt.data)
382 s := NewSectionReader(r, int64(tt.off), int64(tt.n))
383 buf := make([]byte, tt.bufLen)
384 if n, err := s.ReadAt(buf, int64(tt.at)); n != len(tt.exp) || string(buf[:n]) != tt.exp || err != tt.err {
385 t.Fatalf("%d: ReadAt(%d) = %q, %v; expected %q, %v", i, tt.at, buf[:n], err, tt.exp, tt.err)
386 }
387 if _r, off, n := s.Outer(); _r != r || off != int64(tt.off) || n != int64(tt.n) {
388 t.Fatalf("%d: Outer() = %v, %d, %d; expected %v, %d, %d", i, _r, off, n, r, tt.off, tt.n)
389 }
390 }
391 }
392
393 func TestSectionReader_Seek(t *testing.T) {
394
395 br := bytes.NewReader([]byte("foo"))
396 sr := NewSectionReader(br, 0, int64(len("foo")))
397
398 for _, whence := range []int{SeekStart, SeekCurrent, SeekEnd} {
399 for offset := int64(-3); offset <= 4; offset++ {
400 brOff, brErr := br.Seek(offset, whence)
401 srOff, srErr := sr.Seek(offset, whence)
402 if (brErr != nil) != (srErr != nil) || brOff != srOff {
403 t.Errorf("For whence %d, offset %d: bytes.Reader.Seek = (%v, %v) != SectionReader.Seek = (%v, %v)",
404 whence, offset, brOff, brErr, srErr, srOff)
405 }
406 }
407 }
408
409
410 got, err := sr.Seek(100, SeekStart)
411 if err != nil || got != 100 {
412 t.Errorf("Seek = %v, %v; want 100, nil", got, err)
413 }
414
415 n, err := sr.Read(make([]byte, 10))
416 if n != 0 || err != EOF {
417 t.Errorf("Read = %v, %v; want 0, EOF", n, err)
418 }
419 }
420
421 func TestSectionReader_Size(t *testing.T) {
422 tests := []struct {
423 data string
424 want int64
425 }{
426 {"a long sample data, 1234567890", 30},
427 {"", 0},
428 }
429
430 for _, tt := range tests {
431 r := strings.NewReader(tt.data)
432 sr := NewSectionReader(r, 0, int64(len(tt.data)))
433 if got := sr.Size(); got != tt.want {
434 t.Errorf("Size = %v; want %v", got, tt.want)
435 }
436 }
437 }
438
439 func TestSectionReader_Max(t *testing.T) {
440 r := strings.NewReader("abcdef")
441 const maxint64 = 1<<63 - 1
442 sr := NewSectionReader(r, 3, maxint64)
443 n, err := sr.Read(make([]byte, 3))
444 if n != 3 || err != nil {
445 t.Errorf("Read = %v %v, want 3, nil", n, err)
446 }
447 n, err = sr.Read(make([]byte, 3))
448 if n != 0 || err != EOF {
449 t.Errorf("Read = %v, %v, want 0, EOF", n, err)
450 }
451 if _r, off, n := sr.Outer(); _r != r || off != 3 || n != maxint64 {
452 t.Fatalf("Outer = %v, %d, %d; expected %v, %d, %d", _r, off, n, r, 3, int64(maxint64))
453 }
454 }
455
456
457
458 type largeWriter struct {
459 err error
460 }
461
462 func (w largeWriter) Write(p []byte) (int, error) {
463 return len(p) + 1, w.err
464 }
465
466 func TestCopyLargeWriter(t *testing.T) {
467 want := ErrInvalidWrite
468 rb := new(Buffer)
469 wb := largeWriter{}
470 rb.WriteString("hello, world.")
471 if _, err := Copy(wb, rb); err != want {
472 t.Errorf("Copy error: got %v, want %v", err, want)
473 }
474
475 want = errors.New("largeWriterError")
476 rb = new(Buffer)
477 wb = largeWriter{err: want}
478 rb.WriteString("hello, world.")
479 if _, err := Copy(wb, rb); err != want {
480 t.Errorf("Copy error: got %v, want %v", err, want)
481 }
482 }
483
484 func TestNopCloserWriterToForwarding(t *testing.T) {
485 for _, tc := range [...]struct {
486 Name string
487 r Reader
488 }{
489 {"not a WriterTo", Reader(nil)},
490 {"a WriterTo", struct {
491 Reader
492 WriterTo
493 }{}},
494 } {
495 nc := NopCloser(tc.r)
496
497 _, expected := tc.r.(WriterTo)
498 _, got := nc.(WriterTo)
499 if expected != got {
500 t.Errorf("NopCloser incorrectly forwards WriterTo for %s, got %t want %t", tc.Name, got, expected)
501 }
502 }
503 }
504
505 func TestOffsetWriter_Seek(t *testing.T) {
506 tmpfilename := "TestOffsetWriter_Seek"
507 tmpfile, err := os.CreateTemp(t.TempDir(), tmpfilename)
508 if err != nil || tmpfile == nil {
509 t.Fatalf("CreateTemp(%s) failed: %v", tmpfilename, err)
510 }
511 defer tmpfile.Close()
512 w := NewOffsetWriter(tmpfile, 0)
513
514
515 t.Run("errWhence", func(t *testing.T) {
516 for _, whence := range []int{-3, -2, -1, 3, 4, 5} {
517 var offset int64 = 0
518 gotOff, gotErr := w.Seek(offset, whence)
519 if gotOff != 0 || gotErr != ErrWhence {
520 t.Errorf("For whence %d, offset %d, OffsetWriter.Seek got: (%d, %v), want: (%d, %v)",
521 whence, offset, gotOff, gotErr, 0, ErrWhence)
522 }
523 }
524 })
525
526
527 t.Run("errOffset", func(t *testing.T) {
528 for _, whence := range []int{SeekStart, SeekCurrent} {
529 for offset := int64(-3); offset < 0; offset++ {
530 gotOff, gotErr := w.Seek(offset, whence)
531 if gotOff != 0 || gotErr != ErrOffset {
532 t.Errorf("For whence %d, offset %d, OffsetWriter.Seek got: (%d, %v), want: (%d, %v)",
533 whence, offset, gotOff, gotErr, 0, ErrOffset)
534 }
535 }
536 }
537 })
538
539
540 t.Run("normal", func(t *testing.T) {
541 tests := []struct {
542 offset int64
543 whence int
544 returnOff int64
545 }{
546
547 {whence: SeekStart, offset: 1, returnOff: 1},
548 {whence: SeekStart, offset: 2, returnOff: 2},
549 {whence: SeekStart, offset: 3, returnOff: 3},
550 {whence: SeekCurrent, offset: 1, returnOff: 4},
551 {whence: SeekCurrent, offset: 2, returnOff: 6},
552 {whence: SeekCurrent, offset: 3, returnOff: 9},
553 }
554 for idx, tt := range tests {
555 gotOff, gotErr := w.Seek(tt.offset, tt.whence)
556 if gotOff != tt.returnOff || gotErr != nil {
557 t.Errorf("%d:: For whence %d, offset %d, OffsetWriter.Seek got: (%d, %v), want: (%d, <nil>)",
558 idx+1, tt.whence, tt.offset, gotOff, gotErr, tt.returnOff)
559 }
560 }
561 })
562 }
563
564 func TestOffsetWriter_WriteAt(t *testing.T) {
565 const content = "0123456789ABCDEF"
566 contentSize := int64(len(content))
567 tmpdir, err := os.MkdirTemp(t.TempDir(), "TestOffsetWriter_WriteAt")
568 if err != nil {
569 t.Fatal(err)
570 }
571
572 work := func(off, at int64) {
573 position := fmt.Sprintf("off_%d_at_%d", off, at)
574 tmpfile, err := os.CreateTemp(tmpdir, position)
575 if err != nil || tmpfile == nil {
576 t.Fatalf("CreateTemp(%s) failed: %v", position, err)
577 }
578 defer tmpfile.Close()
579
580 var writeN int64
581 var wg sync.WaitGroup
582
583 for step, value := range []byte(content) {
584 wg.Add(1)
585 go func(wg *sync.WaitGroup, tmpfile *os.File, value byte, off, at int64, step int) {
586 defer wg.Done()
587
588 w := NewOffsetWriter(tmpfile, off)
589 n, e := w.WriteAt([]byte{value}, at+int64(step))
590 if e != nil {
591 t.Errorf("WriteAt failed. off: %d, at: %d, step: %d\n error: %v", off, at, step, e)
592 }
593 atomic.AddInt64(&writeN, int64(n))
594 }(&wg, tmpfile, value, off, at, step)
595 }
596 wg.Wait()
597
598
599 buf := make([]byte, contentSize+1)
600 readN, err := tmpfile.ReadAt(buf, off+at)
601 if err != EOF {
602 t.Fatalf("ReadAt failed: %v", err)
603 }
604 readContent := string(buf[:contentSize])
605 if writeN != int64(readN) || writeN != contentSize || readContent != content {
606 t.Fatalf("%s:: WriteAt(%s, %d) error. \ngot n: %v, content: %s \nexpected n: %v, content: %v",
607 position, content, at, readN, readContent, contentSize, content)
608 }
609 }
610 for off := int64(0); off < 2; off++ {
611 for at := int64(0); at < 2; at++ {
612 work(off, at)
613 }
614 }
615 }
616
617 func TestWriteAt_PositionPriorToBase(t *testing.T) {
618 tmpdir := t.TempDir()
619 tmpfilename := "TestOffsetWriter_WriteAt"
620 tmpfile, err := os.CreateTemp(tmpdir, tmpfilename)
621 if err != nil {
622 t.Fatalf("CreateTemp(%s) failed: %v", tmpfilename, err)
623 }
624 defer tmpfile.Close()
625
626
627 offset := int64(10)
628
629 at := int64(-1)
630 w := NewOffsetWriter(tmpfile, offset)
631 _, e := w.WriteAt([]byte("hello"), at)
632 if e == nil {
633 t.Errorf("error expected to be not nil")
634 }
635 }
636
637 func TestOffsetWriter_Write(t *testing.T) {
638 const content = "0123456789ABCDEF"
639 contentSize := len(content)
640 tmpdir := t.TempDir()
641
642 makeOffsetWriter := func(name string) (*OffsetWriter, *os.File) {
643 tmpfilename := "TestOffsetWriter_Write_" + name
644 tmpfile, err := os.CreateTemp(tmpdir, tmpfilename)
645 if err != nil || tmpfile == nil {
646 t.Fatalf("CreateTemp(%s) failed: %v", tmpfilename, err)
647 }
648 return NewOffsetWriter(tmpfile, 0), tmpfile
649 }
650 checkContent := func(name string, f *os.File) {
651
652 buf := make([]byte, contentSize+1)
653 readN, err := f.ReadAt(buf, 0)
654 if err != EOF {
655 t.Fatalf("ReadAt failed, err: %v", err)
656 }
657 readContent := string(buf[:contentSize])
658 if readN != contentSize || readContent != content {
659 t.Fatalf("%s error. \ngot n: %v, content: %s \nexpected n: %v, content: %v",
660 name, readN, readContent, contentSize, content)
661 }
662 }
663
664 var name string
665 name = "Write"
666 t.Run(name, func(t *testing.T) {
667
668
669 w, f := makeOffsetWriter(name)
670 defer f.Close()
671 for _, value := range []byte(content) {
672 n, err := w.Write([]byte{value})
673 if err != nil {
674 t.Fatalf("Write failed, n: %d, err: %v", n, err)
675 }
676 }
677 checkContent(name, f)
678
679
680
681 name = "Copy"
682 w2, f2 := makeOffsetWriter(name)
683 defer f2.Close()
684 Copy(w2, f)
685 checkContent(name, f2)
686 })
687
688
689
690 name = "Write_Of_Copy_WriteTo"
691 t.Run(name, func(t *testing.T) {
692 w, f := makeOffsetWriter(name)
693 defer f.Close()
694 Copy(w, strings.NewReader(content))
695 checkContent(name, f)
696 })
697 }
698
View as plain text