aboutsummaryrefslogtreecommitdiffstats
path: root/utils/ioutil
diff options
context:
space:
mode:
authorSantiago M. Mola <santi@mola.io>2016-11-25 09:25:49 +0100
committerMáximo Cuadros <mcuadros@gmail.com>2016-11-25 09:25:49 +0100
commit9e34f68d980de57631c588aaa910c9ea95ed7c2e (patch)
treeb1bd9f867b757ca46ada2f349d122723dde3529c /utils/ioutil
parent8966c042795509ed17730e50d352ad69901c3da8 (diff)
downloadgo-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.go52
-rw-r--r--utils/ioutil/common_test.go55
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)
+}