package ioutil import ( "bytes" "context" "io/ioutil" "strings" "testing" . "gopkg.in/check.v1" ) func Test(t *testing.T) { TestingT(t) } type CommonSuite struct{} var _ = Suite(&CommonSuite{}) type closer struct { called int } func (c *closer) Close() error { c.called++ return nil } func (s *CommonSuite) TestNonEmptyReader_Empty(c *C) { var buf bytes.Buffer r, err := NonEmptyReader(&buf) c.Assert(err, Equals, ErrEmptyReader) c.Assert(r, IsNil) } func (s *CommonSuite) TestNonEmptyReader_NonEmpty(c *C) { buf := bytes.NewBuffer([]byte("1")) r, err := NonEmptyReader(buf) c.Assert(err, IsNil) c.Assert(r, NotNil) read, err := ioutil.ReadAll(r) c.Assert(err, IsNil) c.Assert(string(read), Equals, "1") } func (s *CommonSuite) TestNewReadCloser(c *C) { buf := bytes.NewBuffer([]byte("1")) closer := &closer{} r := NewReadCloser(buf, closer) read, err := ioutil.ReadAll(r) c.Assert(err, IsNil) c.Assert(string(read), Equals, "1") c.Assert(r.Close(), IsNil) c.Assert(closer.called, Equals, 1) } func (s *CommonSuite) TestNewContextReader(c *C) { buf := bytes.NewBuffer([]byte("12")) ctx, close := context.WithCancel(context.Background()) r := NewContextReader(ctx, buf) b := make([]byte, 1) n, err := r.Read(b) c.Assert(n, Equals, 1) c.Assert(err, IsNil) close() n, err = r.Read(b) c.Assert(n, Equals, 0) c.Assert(err, NotNil) } func (s *CommonSuite) TestNewContextReadCloser(c *C) { buf := NewReadCloser(bytes.NewBuffer([]byte("12")), &closer{}) ctx, close := context.WithCancel(context.Background()) r := NewContextReadCloser(ctx, buf) b := make([]byte, 1) n, err := r.Read(b) c.Assert(n, Equals, 1) c.Assert(err, IsNil) close() n, err = r.Read(b) c.Assert(n, Equals, 0) c.Assert(err, NotNil) c.Assert(r.Close(), IsNil) } func (s *CommonSuite) TestNewContextWriter(c *C) { buf := bytes.NewBuffer(nil) ctx, close := context.WithCancel(context.Background()) r := NewContextWriter(ctx, buf) n, err := r.Write([]byte("1")) c.Assert(n, Equals, 1) c.Assert(err, IsNil) close() n, err = r.Write([]byte("1")) c.Assert(n, Equals, 0) c.Assert(err, NotNil) } func (s *CommonSuite) TestNewContextWriteCloser(c *C) { buf := NewWriteCloser(bytes.NewBuffer(nil), &closer{}) ctx, close := context.WithCancel(context.Background()) w := NewContextWriteCloser(ctx, buf) n, err := w.Write([]byte("1")) c.Assert(n, Equals, 1) c.Assert(err, IsNil) close() n, err = w.Write([]byte("1")) c.Assert(n, Equals, 0) c.Assert(err, NotNil) c.Assert(w.Close(), IsNil) } func (s *CommonSuite) TestNewWriteCloserOnError(c *C) { buf := NewWriteCloser(bytes.NewBuffer(nil), &closer{}) ctx, close := context.WithCancel(context.Background()) var called error w := NewWriteCloserOnError(NewContextWriteCloser(ctx, buf), func(err error) { called = err }) close() w.Write(nil) c.Assert(called, NotNil) } func (s *CommonSuite) TestNewReadCloserOnError(c *C) { buf := NewReadCloser(bytes.NewBuffer(nil), &closer{}) ctx, close := context.WithCancel(context.Background()) var called error w := NewReadCloserOnError(NewContextReadCloser(ctx, buf), func(err error) { called = err }) close() w.Read(nil) c.Assert(called, NotNil) } func ExampleCheckClose() { // CheckClose is commonly used with named return values f := func() (err error) { // Get a io.ReadCloser r := ioutil.NopCloser(strings.NewReader("foo")) // defer CheckClose call with an io.Closer and pointer to error defer CheckClose(r, &err) // ... work with r ... // if err is not nil, CheckClose will assign any close errors to it return err } err := f() if err != nil { panic(err) } }