diff options
Diffstat (limited to 'src/pkg/bufio/bufio_test.go')
-rw-r--r-- | src/pkg/bufio/bufio_test.go | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/src/pkg/bufio/bufio_test.go b/src/pkg/bufio/bufio_test.go new file mode 100644 index 000000000..6e5135df7 --- /dev/null +++ b/src/pkg/bufio/bufio_test.go @@ -0,0 +1,298 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bufio + +import ( + "bufio"; + "fmt"; + "io"; + "os"; + "testing"; + "testing/iotest"; +) + +// Reads from a reader and rot13s the result. +type rot13Reader struct { + r io.Reader +} + +func newRot13Reader(r io.Reader) *rot13Reader { + r13 := new(rot13Reader); + r13.r = r; + return r13 +} + +func (r13 *rot13Reader) Read(p []byte) (int, os.Error) { + n, e := r13.r.Read(p); + if e != nil { + return n, e + } + for i := 0; i < n; i++ { + c := p[i] | 0x20; // lowercase byte + if 'a' <= c && c <= 'm' { + p[i] += 13; + } else if 'n' <= c && c <= 'z' { + p[i] -= 13; + } + } + return n, nil +} + +// Call ReadByte to accumulate the text of a file +func readBytes(buf *Reader) string { + var b [1000]byte; + nb := 0; + for { + c, e := buf.ReadByte(); + if e == io.ErrEOF { + break + } + if e != nil { + panic("Data: "+e.String()) + } + b[nb] = c; + nb++; + } + return string(b[0:nb]) +} + +func TestReaderSimple(t *testing.T) { + data := io.StringBytes("hello world"); + b := NewReader(io.NewByteReader(data)); + if s := readBytes(b); s != "hello world" { + t.Errorf("simple hello world test failed: got %q", s); + } + + b = NewReader(newRot13Reader(io.NewByteReader(data))); + if s := readBytes(b); s != "uryyb jbeyq" { + t.Error("rot13 hello world test failed: got %q", s); + } +} + + +type readMaker struct { + name string; + fn func(io.Reader) io.Reader; +} +var readMakers = []readMaker { + readMaker{ "full", func(r io.Reader) io.Reader { return r } }, + readMaker{ "byte", iotest.OneByteReader }, + readMaker{ "half", iotest.HalfReader }, +} + +// Call ReadLineString (which ends up calling everything else) +// to accumulate the text of a file. +func readLines(b *Reader) string { + s := ""; + for { + s1, e := b.ReadLineString('\n', true); + if e == io.ErrEOF { + break + } + if e != nil { + panic("GetLines: "+e.String()) + } + s += s1 + } + return s +} + +// Call Read to accumulate the text of a file +func reads(buf *Reader, m int) string { + var b [1000]byte; + nb := 0; + for { + n, e := buf.Read(b[nb:nb+m]); + nb += n; + if e == io.ErrEOF { + break + } + } + return string(b[0:nb]) +} + +type bufReader struct { + name string; + fn func(*Reader) string; +} +var bufreaders = []bufReader { + bufReader{ "1", func(b *Reader) string { return reads(b, 1) } }, + bufReader{ "2", func(b *Reader) string { return reads(b, 2) } }, + bufReader{ "3", func(b *Reader) string { return reads(b, 3) } }, + bufReader{ "4", func(b *Reader) string { return reads(b, 4) } }, + bufReader{ "5", func(b *Reader) string { return reads(b, 5) } }, + bufReader{ "7", func(b *Reader) string { return reads(b, 7) } }, + bufReader{ "bytes", readBytes }, + bufReader{ "lines", readLines }, +} + +var bufsizes = []int { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 23, 32, 46, 64, 93, 128, 1024, 4096 +} + +func TestReader(t *testing.T) { + var texts [31]string; + str := ""; + all := ""; + for i := 0; i < len(texts)-1; i++ { + texts[i] = str + "\n"; + all += texts[i]; + str += string(i%26+'a') + } + texts[len(texts)-1] = all; + + for h := 0; h < len(texts); h++ { + text := texts[h]; + textbytes := io.StringBytes(text); + for i := 0; i < len(readMakers); i++ { + for j := 0; j < len(bufreaders); j++ { + for k := 0; k < len(bufsizes); k++ { + readmaker := readMakers[i]; + bufreader := bufreaders[j]; + bufsize := bufsizes[k]; + read := readmaker.fn(io.NewByteReader(textbytes)); + buf, e := NewReaderSize(read, bufsize); + s := bufreader.fn(buf); + if s != text { + t.Errorf("reader=%s fn=%s bufsize=%d want=%q got=%q", + readmaker.name, bufreader.name, bufsize, text, s); + } + } + } + } + } +} + +func TestWriter(t *testing.T) { + var data [8192]byte; + + for i := 0; i < len(data); i++ { + data[i] = byte(' '+ i%('~'-' ')); + } + w := new(io.ByteBuffer); + for i := 0; i < len(bufsizes); i++ { + for j := 0; j < len(bufsizes); j++ { + nwrite := bufsizes[i]; + bs := bufsizes[j]; + + // Write nwrite bytes using buffer size bs. + // Check that the right amount makes it out + // and that the data is correct. + + w.Reset(); + buf, e := NewWriterSize(w, bs); + context := fmt.Sprintf("nwrite=%d bufsize=%d", nwrite, bs); + if e != nil { + t.Errorf("%s: NewWriterSize %d: %v", context, bs, e); + continue; + } + n, e1 := buf.Write(data[0:nwrite]); + if e1 != nil || n != nwrite { + t.Errorf("%s: buf.Write %d = %d, %v", context, nwrite, n, e1); + continue; + } + if e = buf.Flush(); e != nil { + t.Errorf("%s: buf.Flush = %v", context, e); + } + + written := w.Data(); + if len(written) != nwrite { + t.Errorf("%s: %d bytes written", context, len(written)); + } + for l := 0; l < len(written); l++ { + if written[i] != data[i] { + t.Errorf("%s: wrong bytes written"); + t.Errorf("want=%s", data[0:len(written)]); + t.Errorf("have=%s", written); + } + } + } + } +} + +// Check that write errors are returned properly. + +type errorWriterTest struct { + n, m int; + err os.Error; + expect os.Error; +} + +func (w errorWriterTest) Write(p []byte) (int, os.Error) { + return len(p)*w.n/w.m, w.err; +} + +var errorWriterTests = []errorWriterTest { + errorWriterTest{ 0, 1, nil, io.ErrShortWrite }, + errorWriterTest{ 1, 2, nil, io.ErrShortWrite }, + errorWriterTest{ 1, 1, nil, nil }, + errorWriterTest{ 0, 1, os.EPIPE, os.EPIPE }, + errorWriterTest{ 1, 2, os.EPIPE, os.EPIPE }, + errorWriterTest{ 1, 1, os.EPIPE, os.EPIPE }, +} + +func TestWriteErrors(t *testing.T) { + for i, w := range errorWriterTests { + buf := NewWriter(w); + n, e := buf.Write(io.StringBytes("hello world")); + if e != nil { + t.Errorf("Write hello to %v: %v", w, e); + continue; + } + e = buf.Flush(); + if e != w.expect { + t.Errorf("Flush %v: got %v, wanted %v", w, e, w.expect); + } + } +} + +func TestNewReaderSizeIdempotent(t *testing.T) { + const BufSize = 1000; + b, err := NewReaderSize(io.NewByteReader(io.StringBytes("hello world")), BufSize); + if err != nil { + t.Error("NewReaderSize create fail", err); + } + // Does it recognize itself? + b1, err2 := NewReaderSize(b, BufSize); + if err2 != nil { + t.Error("NewReaderSize #2 create fail", err2); + } + if b1 != b { + t.Error("NewReaderSize did not detect underlying Reader"); + } + // Does it wrap if existing buffer is too small? + b2, err3 := NewReaderSize(b, 2*BufSize); + if err3 != nil { + t.Error("NewReaderSize #3 create fail", err3); + } + if b2 == b { + t.Error("NewReaderSize did not enlarge buffer"); + } +} + +func TestNewWriterSizeIdempotent(t *testing.T) { + const BufSize = 1000; + b, err := NewWriterSize(new(io.ByteBuffer), BufSize); + if err != nil { + t.Error("NewWriterSize create fail", err); + } + // Does it recognize itself? + b1, err2 := NewWriterSize(b, BufSize); + if err2 != nil { + t.Error("NewWriterSize #2 create fail", err2); + } + if b1 != b { + t.Error("NewWriterSize did not detect underlying Writer"); + } + // Does it wrap if existing buffer is too small? + b2, err3 := NewWriterSize(b, 2*BufSize); + if err3 != nil { + t.Error("NewWriterSize #3 create fail", err3); + } + if b2 == b { + t.Error("NewWriterSize did not enlarge buffer"); + } +} |