diff options
author | Santiago M. Mola <santi@mola.io> | 2016-11-25 09:25:49 +0100 |
---|---|---|
committer | Máximo Cuadros <mcuadros@gmail.com> | 2016-11-25 09:25:49 +0100 |
commit | 9e34f68d980de57631c588aaa910c9ea95ed7c2e (patch) | |
tree | b1bd9f867b757ca46ada2f349d122723dde3529c /utils/ioutil | |
parent | 8966c042795509ed17730e50d352ad69901c3da8 (diff) | |
download | go-git-9e34f68d980de57631c588aaa910c9ea95ed7c2e.tar.gz |
plumbing/transport: add common tests and fixes. (#136)
* plumbing/transport: add common tests and fixes.
* add common test suite for different transport implementations.
* fix different behaviour on error handling for ssh and http.
fixes issue #123.
* support detecting unexisting repositories with SSH + GitHub/Bitbucket
(apparently, there is no standard for all SSH servers).
* remove ssh.NewClient (only DefaultClient makes sense at the moment).
* make ssh.Client and http.Client private.
* utils/ioutil: utilities to work with io interfaces.
* * transport: test actual objects fetched, not just packfile size.
* * fix doc typo.
* * improve UploadPackRequest.IsEmpty
Diffstat (limited to 'utils/ioutil')
-rw-r--r-- | utils/ioutil/common.go | 52 | ||||
-rw-r--r-- | utils/ioutil/common_test.go | 55 |
2 files changed, 107 insertions, 0 deletions
diff --git a/utils/ioutil/common.go b/utils/ioutil/common.go new file mode 100644 index 0000000..13db692 --- /dev/null +++ b/utils/ioutil/common.go @@ -0,0 +1,52 @@ +package ioutil + +import ( + "bufio" + "errors" + "io" +) + +type readPeeker interface { + io.Reader + Peek(int) ([]byte, error) +} + +var ( + ErrEmptyReader = errors.New("reader is empty") +) + +// NonEmptyReader takes a reader and returns it if it is not empty, or +// `ErrEmptyReader` if it is empty. If there is an error when reading the first +// byte of the given reader, it will be propagated. +func NonEmptyReader(r io.Reader) (io.Reader, error) { + pr, ok := r.(readPeeker) + if !ok { + pr = bufio.NewReader(r) + } + + _, err := pr.Peek(1) + if err == io.EOF { + return nil, ErrEmptyReader + } + + if err != nil { + return nil, err + } + + return pr, nil +} + +type readCloser struct { + io.Reader + closer io.Closer +} + +func (r *readCloser) Close() error { + return r.closer.Close() +} + +// NewReadCloser creates an `io.ReadCloser` with the given `io.Reader` and +// `io.Closer`. +func NewReadCloser(r io.Reader, c io.Closer) io.ReadCloser { + return &readCloser{Reader: r, closer: c} +} diff --git a/utils/ioutil/common_test.go b/utils/ioutil/common_test.go new file mode 100644 index 0000000..f5017f7 --- /dev/null +++ b/utils/ioutil/common_test.go @@ -0,0 +1,55 @@ +package ioutil + +import ( + "bytes" + "io/ioutil" + "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) +} |