From c2bb17b947a1a1178d9bdca2a59b29677e153619 Mon Sep 17 00:00:00 2001 From: Marius Date: Thu, 13 Oct 2016 18:08:34 +0200 Subject: [PATCH] Refactor remaining tests to subtest style --- cors_test.go | 65 +++--- get_test.go | 8 +- handler_mock_test.go | 43 +++- handler_test.go | 45 ---- options_test.go | 55 +++-- patch_test.go | 518 +++++++++++++++++++------------------------ utils_test.go | 26 +-- 7 files changed, 343 insertions(+), 417 deletions(-) delete mode 100644 handler_test.go diff --git a/cors_test.go b/cors_test.go index 6f42e07..0dfb537 100644 --- a/cors_test.go +++ b/cors_test.go @@ -8,37 +8,42 @@ import ( ) func TestCORS(t *testing.T) { - store := NewStoreComposer() - store.UseCore(zeroStore{}) - handler, _ := NewHandler(Config{ - StoreComposer: store, + SubTest(t, "Preflight", func(t *testing.T, store *MockFullDataStore) { + handler, _ := NewHandler(Config{ + DataStore: store, + }) + + (&httpTest{ + Method: "OPTIONS", + ReqHeader: map[string]string{ + "Origin": "tus.io", + }, + Code: http.StatusOK, + ResHeader: map[string]string{ + "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Upload-Length, Upload-Offset, Tus-Resumable, Upload-Metadata", + "Access-Control-Allow-Methods": "POST, GET, HEAD, PATCH, DELETE, OPTIONS", + "Access-Control-Max-Age": "86400", + "Access-Control-Allow-Origin": "tus.io", + }, + }).Run(handler, t) }) - (&httpTest{ - Name: "Preflight request", - Method: "OPTIONS", - ReqHeader: map[string]string{ - "Origin": "tus.io", - }, - Code: http.StatusOK, - ResHeader: map[string]string{ - "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Upload-Length, Upload-Offset, Tus-Resumable, Upload-Metadata", - "Access-Control-Allow-Methods": "POST, GET, HEAD, PATCH, DELETE, OPTIONS", - "Access-Control-Max-Age": "86400", - "Access-Control-Allow-Origin": "tus.io", - }, - }).Run(handler, t) + SubTest(t, "Request", func(t *testing.T, store *MockFullDataStore) { + handler, _ := NewHandler(Config{ + DataStore: store, + }) - (&httpTest{ - Name: "Actual request", - Method: "GET", - ReqHeader: map[string]string{ - "Origin": "tus.io", - }, - Code: http.StatusMethodNotAllowed, - ResHeader: map[string]string{ - "Access-Control-Expose-Headers": "Upload-Offset, Location, Upload-Length, Tus-Version, Tus-Resumable, Tus-Max-Size, Tus-Extension, Upload-Metadata", - "Access-Control-Allow-Origin": "tus.io", - }, - }).Run(handler, t) + (&httpTest{ + Name: "Actual request", + Method: "GET", + ReqHeader: map[string]string{ + "Origin": "tus.io", + }, + Code: http.StatusMethodNotAllowed, + ResHeader: map[string]string{ + "Access-Control-Expose-Headers": "Upload-Offset, Location, Upload-Length, Tus-Version, Tus-Resumable, Tus-Max-Size, Tus-Extension, Upload-Metadata", + "Access-Control-Allow-Origin": "tus.io", + }, + }).Run(handler, t) + }) } diff --git a/get_test.go b/get_test.go index e7d079e..8c8cc24 100644 --- a/get_test.go +++ b/get_test.go @@ -19,12 +19,12 @@ func (reader *closingStringReader) Close() error { return nil } -var reader = &closingStringReader{ - Reader: strings.NewReader("hello"), -} - func TestGet(t *testing.T) { SubTest(t, "Download", func(t *testing.T, store *MockFullDataStore) { + reader := &closingStringReader{ + Reader: strings.NewReader("hello"), + } + gomock.InOrder( store.EXPECT().GetInfo("yes").Return(FileInfo{ Offset: 5, diff --git a/handler_mock_test.go b/handler_mock_test.go index fd292fd..b323d61 100644 --- a/handler_mock_test.go +++ b/handler_mock_test.go @@ -1,5 +1,5 @@ // Automatically generated by MockGen. DO NOT EDIT! -// Source: handler_test.go +// Source: utils_test.go package tusd_test @@ -94,3 +94,44 @@ func (_m *MockFullDataStore) GetReader(id string) (io.Reader, error) { func (_mr *_MockFullDataStoreRecorder) GetReader(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "GetReader", arg0) } + +// Mock of Locker interface +type MockLocker struct { + ctrl *gomock.Controller + recorder *_MockLockerRecorder +} + +// Recorder for MockLocker (not exported) +type _MockLockerRecorder struct { + mock *MockLocker +} + +func NewMockLocker(ctrl *gomock.Controller) *MockLocker { + mock := &MockLocker{ctrl: ctrl} + mock.recorder = &_MockLockerRecorder{mock} + return mock +} + +func (_m *MockLocker) EXPECT() *_MockLockerRecorder { + return _m.recorder +} + +func (_m *MockLocker) LockUpload(id string) error { + ret := _m.ctrl.Call(_m, "LockUpload", id) + ret0, _ := ret[0].(error) + return ret0 +} + +func (_mr *_MockLockerRecorder) LockUpload(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCall(_mr.mock, "LockUpload", arg0) +} + +func (_m *MockLocker) UnlockUpload(id string) error { + ret := _m.ctrl.Call(_m, "UnlockUpload", id) + ret0, _ := ret[0].(error) + return ret0 +} + +func (_mr *_MockLockerRecorder) UnlockUpload(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCall(_mr.mock, "UnlockUpload", arg0) +} diff --git a/handler_test.go b/handler_test.go deleted file mode 100644 index 73ce184..0000000 --- a/handler_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package tusd_test - -import ( - "net/http" - "strings" - "testing" - - "github.com/golang/mock/gomock" - . "github.com/tus/tusd" -) - -func TestMethodOverride(t *testing.T) { - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - store := NewMockFullDataStore(mockCtrl) - - store.EXPECT().GetInfo("yes").Return(FileInfo{ - Offset: 5, - Size: 20, - }, nil) - - store.EXPECT().WriteChunk("yes", int64(5), NewReaderMatcher("hello")).Return(int64(5), nil) - - handler, _ := NewHandler(Config{ - DataStore: store, - }) - - (&httpTest{ - Name: "Successful request", - Method: "POST", - URL: "yes", - ReqHeader: map[string]string{ - "Tus-Resumable": "1.0.0", - "Upload-Offset": "5", - "Content-Type": "application/offset+octet-stream", - "X-HTTP-Method-Override": "PATCH", - }, - ReqBody: strings.NewReader("hello"), - Code: http.StatusNoContent, - ResHeader: map[string]string{ - "Upload-Offset": "10", - }, - }).Run(handler, t) -} diff --git a/options_test.go b/options_test.go index 26febd8..2194035 100644 --- a/options_test.go +++ b/options_test.go @@ -8,31 +8,38 @@ import ( ) func TestOptions(t *testing.T) { - store := NewStoreComposer() - store.UseCore(NewMockFullDataStore(nil)) - handler, _ := NewHandler(Config{ - StoreComposer: store, - MaxSize: 400, + SubTest(t, "Discovery", func(t *testing.T, store *MockFullDataStore) { + composer := NewStoreComposer() + composer.UseCore(store) + + handler, _ := NewHandler(Config{ + StoreComposer: composer, + MaxSize: 400, + }) + + (&httpTest{ + Method: "OPTIONS", + ResHeader: map[string]string{ + "Tus-Extension": "creation,creation-with-upload", + "Tus-Version": "1.0.0", + "Tus-Resumable": "1.0.0", + "Tus-Max-Size": "400", + }, + Code: http.StatusOK, + }).Run(handler, t) }) - (&httpTest{ - Name: "Successful request", - Method: "OPTIONS", - Code: http.StatusOK, - ResHeader: map[string]string{ - "Tus-Extension": "creation,creation-with-upload", - "Tus-Version": "1.0.0", - "Tus-Resumable": "1.0.0", - "Tus-Max-Size": "400", - }, - }).Run(handler, t) + SubTest(t, "InvalidVersion", func(t *testing.T, store *MockFullDataStore) { + handler, _ := NewHandler(Config{ + DataStore: store, + }) - (&httpTest{ - Name: "Invalid or unsupported version", - Method: "POST", - ReqHeader: map[string]string{ - "Tus-Resumable": "foo", - }, - Code: http.StatusPreconditionFailed, - }).Run(handler, t) + (&httpTest{ + Method: "POST", + ReqHeader: map[string]string{ + "Tus-Resumable": "foo", + }, + Code: http.StatusPreconditionFailed, + }).Run(handler, t) + }) } diff --git a/patch_test.go b/patch_test.go index 162e609..25bf058 100644 --- a/patch_test.go +++ b/patch_test.go @@ -1,326 +1,254 @@ package tusd_test import ( - "io" "io/ioutil" "net/http" "os" "strings" "testing" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" . "github.com/tus/tusd" ) -type patchStore struct { - zeroStore - t *assert.Assertions - called bool -} - -func (s patchStore) GetInfo(id string) (FileInfo, error) { - if id != "yes" { - return FileInfo{}, os.ErrNotExist - } - - return FileInfo{ - ID: id, - Offset: 5, - Size: 10, - }, nil -} - -func (s patchStore) WriteChunk(id string, offset int64, src io.Reader) (int64, error) { - s.t.False(s.called, "WriteChunk must be called only once") - s.called = true - - s.t.Equal(int64(5), offset) - - data, err := ioutil.ReadAll(src) - s.t.Nil(err) - s.t.Equal("hello", string(data)) - - return 5, nil -} - func TestPatch(t *testing.T) { - a := assert.New(t) + SubTest(t, "UploadChunk", func(t *testing.T, store *MockFullDataStore) { + gomock.InOrder( + store.EXPECT().GetInfo("yes").Return(FileInfo{ + ID: "yes", + Offset: 5, + Size: 10, + }, nil), + store.EXPECT().WriteChunk("yes", int64(5), NewReaderMatcher("hello")).Return(int64(5), nil), + ) - handler, _ := NewHandler(Config{ - MaxSize: 100, - DataStore: patchStore{ - t: a, - }, - NotifyCompleteUploads: true, + handler, _ := NewHandler(Config{ + DataStore: store, + NotifyCompleteUploads: true, + }) + + c := make(chan FileInfo, 1) + handler.CompleteUploads = c + + (&httpTest{ + Method: "PATCH", + URL: "yes", + ReqHeader: map[string]string{ + "Tus-Resumable": "1.0.0", + "Content-Type": "application/offset+octet-stream", + "Upload-Offset": "5", + }, + ReqBody: strings.NewReader("hello"), + Code: http.StatusNoContent, + ResHeader: map[string]string{ + "Upload-Offset": "10", + }, + }).Run(handler, t) + + a := assert.New(t) + info := <-c + a.Equal("yes", info.ID) + a.EqualValues(int64(10), info.Size) + a.Equal(int64(10), info.Offset) }) - c := make(chan FileInfo, 1) - handler.CompleteUploads = c + SubTest(t, "MethodOverriding", func(t *testing.T, store *MockFullDataStore) { + gomock.InOrder( + store.EXPECT().GetInfo("yes").Return(FileInfo{ + ID: "yes", + Offset: 5, + Size: 10, + }, nil), + store.EXPECT().WriteChunk("yes", int64(5), NewReaderMatcher("hello")).Return(int64(5), nil), + ) - (&httpTest{ - Name: "Successful request", - Method: "PATCH", - URL: "yes", - ReqHeader: map[string]string{ - "Tus-Resumable": "1.0.0", - "Content-Type": "application/offset+octet-stream", - "Upload-Offset": "5", - }, - ReqBody: strings.NewReader("hello"), - Code: http.StatusNoContent, - ResHeader: map[string]string{ - "Upload-Offset": "10", - }, - }).Run(handler, t) + handler, _ := NewHandler(Config{ + DataStore: store, + }) - info := <-c - a.Equal("yes", info.ID) - a.Equal(int64(10), info.Size) - a.Equal(int64(10), info.Offset) - - (&httpTest{ - Name: "Non-existing file", - Method: "PATCH", - URL: "no", - ReqHeader: map[string]string{ - "Tus-Resumable": "1.0.0", - "Content-Type": "application/offset+octet-stream", - "Upload-Offset": "5", - }, - Code: http.StatusNotFound, - }).Run(handler, t) - - (&httpTest{ - Name: "Wrong offset", - Method: "PATCH", - URL: "yes", - ReqHeader: map[string]string{ - "Tus-Resumable": "1.0.0", - "Content-Type": "application/offset+octet-stream", - "Upload-Offset": "4", - }, - Code: http.StatusConflict, - }).Run(handler, t) - - (&httpTest{ - Name: "Exceeding file size", - Method: "PATCH", - URL: "yes", - ReqHeader: map[string]string{ - "Tus-Resumable": "1.0.0", - "Content-Type": "application/offset+octet-stream", - "Upload-Offset": "5", - }, - ReqBody: strings.NewReader("hellothisismorethan15bytes"), - Code: http.StatusRequestEntityTooLarge, - }).Run(handler, t) -} - -type overflowPatchStore struct { - zeroStore - t *assert.Assertions - called bool -} - -func (s overflowPatchStore) GetInfo(id string) (FileInfo, error) { - if id != "yes" { - return FileInfo{}, os.ErrNotExist - } - - return FileInfo{ - Offset: 5, - Size: 20, - }, nil -} - -func (s overflowPatchStore) WriteChunk(id string, offset int64, src io.Reader) (int64, error) { - s.t.False(s.called, "WriteChunk must be called only once") - s.called = true - - s.t.Equal(int64(5), offset) - - data, err := ioutil.ReadAll(src) - s.t.Nil(err) - s.t.Equal("hellothisismore", string(data)) - - return 15, nil -} - -// noEOFReader implements io.Reader, io.Writer, io.Closer but does not return -// an io.EOF when the internal buffer is empty. This way we can simulate slow -// networks. -type noEOFReader struct { - closed bool - buffer []byte -} - -func (r *noEOFReader) Read(dst []byte) (int, error) { - if r.closed && len(r.buffer) == 0 { - return 0, io.EOF - } - - n := copy(dst, r.buffer) - r.buffer = r.buffer[n:] - return n, nil -} - -func (r *noEOFReader) Close() error { - r.closed = true - return nil -} - -func (r *noEOFReader) Write(src []byte) (int, error) { - r.buffer = append(r.buffer, src...) - return len(src), nil -} - -func TestPatchOverflow(t *testing.T) { - handler, _ := NewHandler(Config{ - MaxSize: 100, - DataStore: overflowPatchStore{ - t: assert.New(t), - }, + (&httpTest{ + Method: "POST", + URL: "yes", + ReqHeader: map[string]string{ + "Tus-Resumable": "1.0.0", + "Upload-Offset": "5", + "Content-Type": "application/offset+octet-stream", + "X-HTTP-Method-Override": "PATCH", + }, + ReqBody: strings.NewReader("hello"), + Code: http.StatusNoContent, + ResHeader: map[string]string{ + "Upload-Offset": "10", + }, + }).Run(handler, t) }) - body := &noEOFReader{} + SubTest(t, "UploadChunkToFinished", func(t *testing.T, store *MockFullDataStore) { + store.EXPECT().GetInfo("yes").Return(FileInfo{ + Offset: 20, + Size: 20, + }, nil) - body.Write([]byte("hellothisismorethan15bytes")) - body.Close() + handler, _ := NewHandler(Config{ + DataStore: store, + }) - (&httpTest{ - Name: "Too big body exceeding file size", - Method: "PATCH", - URL: "yes", - ReqHeader: map[string]string{ - "Tus-Resumable": "1.0.0", - "Content-Type": "application/offset+octet-stream", - "Upload-Offset": "5", - "Content-Length": "3", - }, - ReqBody: body, - Code: http.StatusNoContent, - }).Run(handler, t) -} - -const ( - LOCK = iota - INFO - WRITE - UNLOCK - END -) - -type lockingPatchStore struct { - zeroStore - callOrder chan int -} - -func (s lockingPatchStore) GetInfo(id string) (FileInfo, error) { - s.callOrder <- INFO - - return FileInfo{ - Offset: 0, - Size: 20, - }, nil -} - -func (s lockingPatchStore) WriteChunk(id string, offset int64, src io.Reader) (int64, error) { - s.callOrder <- WRITE - - return 5, nil -} - -func (s lockingPatchStore) LockUpload(id string) error { - s.callOrder <- LOCK - return nil -} - -func (s lockingPatchStore) UnlockUpload(id string) error { - s.callOrder <- UNLOCK - return nil -} - -func TestLockingPatch(t *testing.T) { - callOrder := make(chan int, 10) - - handler, _ := NewHandler(Config{ - DataStore: lockingPatchStore{ - callOrder: callOrder, - }, + (&httpTest{ + Method: "PATCH", + URL: "yes", + ReqHeader: map[string]string{ + "Tus-Resumable": "1.0.0", + "Content-Type": "application/offset+octet-stream", + "Upload-Offset": "20", + }, + ReqBody: strings.NewReader(""), + Code: http.StatusNoContent, + ResHeader: map[string]string{ + "Upload-Offset": "20", + }, + }).Run(handler, t) }) - (&httpTest{ - Name: "Uploading to locking store", - Method: "PATCH", - URL: "yes", - ReqHeader: map[string]string{ - "Tus-Resumable": "1.0.0", - "Content-Type": "application/offset+octet-stream", - "Upload-Offset": "0", - }, - ReqBody: strings.NewReader("hello"), - Code: http.StatusNoContent, - }).Run(handler, t) + SubTest(t, "UploadNotFoundFail", func(t *testing.T, store *MockFullDataStore) { + store.EXPECT().GetInfo("no").Return(FileInfo{}, os.ErrNotExist) - callOrder <- END - close(callOrder) + handler, _ := NewHandler(Config{ + DataStore: store, + }) - if <-callOrder != LOCK { - t.Error("expected call to LockUpload") - } - - if <-callOrder != INFO { - t.Error("expected call to GetInfo") - } - - if <-callOrder != WRITE { - t.Error("expected call to WriteChunk") - } - - if <-callOrder != UNLOCK { - t.Error("expected call to UnlockUpload") - } - - if <-callOrder != END { - t.Error("expected no more calls to happen") - } -} - -type finishedPatchStore struct { - zeroStore -} - -func (s finishedPatchStore) GetInfo(id string) (FileInfo, error) { - return FileInfo{ - Offset: 20, - Size: 20, - }, nil -} - -func (s finishedPatchStore) WriteChunk(id string, offset int64, src io.Reader) (int64, error) { - panic("WriteChunk must not be called") -} - -func TestFinishedPatch(t *testing.T) { - - handler, _ := NewHandler(Config{ - DataStore: finishedPatchStore{}, + (&httpTest{ + Method: "PATCH", + URL: "no", + ReqHeader: map[string]string{ + "Tus-Resumable": "1.0.0", + "Content-Type": "application/offset+octet-stream", + "Upload-Offset": "5", + }, + Code: http.StatusNotFound, + }).Run(handler, t) }) - (&httpTest{ - Name: "Uploading to finished upload", - Method: "PATCH", - URL: "yes", - ReqHeader: map[string]string{ - "Tus-Resumable": "1.0.0", - "Content-Type": "application/offset+octet-stream", - "Upload-Offset": "20", - }, - ReqBody: strings.NewReader(""), - Code: http.StatusNoContent, - ResHeader: map[string]string{ - "Upload-Offset": "20", - }, - }).Run(handler, t) + SubTest(t, "MissmatchingOffsetFail", func(t *testing.T, store *MockFullDataStore) { + store.EXPECT().GetInfo("yes").Return(FileInfo{ + Offset: 5, + }, nil) + + handler, _ := NewHandler(Config{ + DataStore: store, + }) + + (&httpTest{ + Method: "PATCH", + URL: "yes", + ReqHeader: map[string]string{ + "Tus-Resumable": "1.0.0", + "Content-Type": "application/offset+octet-stream", + "Upload-Offset": "4", + }, + Code: http.StatusConflict, + }).Run(handler, t) + }) + + SubTest(t, "ExceedingMaxSizeFail", func(t *testing.T, store *MockFullDataStore) { + store.EXPECT().GetInfo("yes").Return(FileInfo{ + Offset: 5, + Size: 10, + }, nil) + + handler, _ := NewHandler(Config{ + DataStore: store, + }) + + (&httpTest{ + Method: "PATCH", + URL: "yes", + ReqHeader: map[string]string{ + "Tus-Resumable": "1.0.0", + "Content-Type": "application/offset+octet-stream", + "Upload-Offset": "5", + }, + ReqBody: strings.NewReader("hellothisismorethan15bytes"), + Code: http.StatusRequestEntityTooLarge, + }).Run(handler, t) + }) + + SubTest(t, "OverflowWithoutLength", func(t *testing.T, store *MockFullDataStore) { + // In this test we attempt to upload more than 15 bytes to an upload + // which has only space for 15 bytes (offset of 5 and size of 20). + // The request does not contain the Content-Length header and the handler + // therefore does not know the chunk's size before. The wanted behavior + // is that even if the uploader supplies more than 15 bytes, we only + // pass 15 bytes to the data store and ignore the rest. + + gomock.InOrder( + store.EXPECT().GetInfo("yes").Return(FileInfo{ + Offset: 5, + Size: 20, + }, nil), + store.EXPECT().WriteChunk("yes", int64(5), NewReaderMatcher("hellothisismore")).Return(int64(15), nil), + ) + + handler, _ := NewHandler(Config{ + DataStore: store, + }) + + // Wrap the string.Reader in a NopCloser to hide its type. else + // http.NewRequest() will detect the we supply a strings.Reader as body + // and use this information to set the Content-Length header which we + // explicitly do not want (see comment above for reason). + body := ioutil.NopCloser(strings.NewReader("hellothisismorethan15bytes")) + + (&httpTest{ + Method: "PATCH", + URL: "yes", + ReqHeader: map[string]string{ + "Tus-Resumable": "1.0.0", + "Content-Type": "application/offset+octet-stream", + "Upload-Offset": "5", + }, + ReqBody: body, + Code: http.StatusNoContent, + ResHeader: map[string]string{ + "Upload-Offset": "20", + }, + }).Run(handler, t) + }) + + SubTest(t, "Locker", func(t *testing.T, store *MockFullDataStore) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + locker := NewMockLocker(ctrl) + + gomock.InOrder( + locker.EXPECT().LockUpload("yes").Return(nil), + store.EXPECT().GetInfo("yes").Return(FileInfo{ + Offset: 0, + Size: 20, + }, nil), + store.EXPECT().WriteChunk("yes", int64(0), NewReaderMatcher("hello")).Return(int64(5), nil), + locker.EXPECT().UnlockUpload("yes").Return(nil), + ) + + composer := NewStoreComposer() + composer.UseCore(store) + composer.UseLocker(locker) + + handler, _ := NewHandler(Config{ + StoreComposer: composer, + }) + + (&httpTest{ + Method: "PATCH", + URL: "yes", + ReqHeader: map[string]string{ + "Tus-Resumable": "1.0.0", + "Content-Type": "application/offset+octet-stream", + "Upload-Offset": "0", + }, + ReqBody: strings.NewReader("hello"), + Code: http.StatusNoContent, + }).Run(handler, t) + }) } diff --git a/utils_test.go b/utils_test.go index 4449217..e1bad9b 100644 --- a/utils_test.go +++ b/utils_test.go @@ -11,22 +11,8 @@ import ( "github.com/golang/mock/gomock" "github.com/tus/tusd" - . "github.com/tus/tusd" ) -type zeroStore struct{} - -func (store zeroStore) NewUpload(info FileInfo) (string, error) { - return "", nil -} -func (store zeroStore) WriteChunk(id string, offset int64, src io.Reader) (int64, error) { - return 0, nil -} - -func (store zeroStore) GetInfo(id string) (FileInfo, error) { - return FileInfo{}, nil -} - type FullDataStore interface { tusd.DataStore tusd.TerminaterDataStore @@ -34,6 +20,10 @@ type FullDataStore interface { tusd.GetReaderDataStore } +type Locker interface { + tusd.LockerDataStore +} + type httpTest struct { Name string @@ -79,17 +69,17 @@ func (test *httpTest) Run(handler http.Handler, t *testing.T) *httptest.Response return w } -type ReaderMatcher struct { +type readerMatcher struct { expect string } func NewReaderMatcher(expect string) gomock.Matcher { - return ReaderMatcher{ + return readerMatcher{ expect: expect, } } -func (m ReaderMatcher) Matches(x interface{}) bool { +func (m readerMatcher) Matches(x interface{}) bool { input, ok := x.(io.Reader) if !ok { return false @@ -104,6 +94,6 @@ func (m ReaderMatcher) Matches(x interface{}) bool { return reflect.DeepEqual(m.expect, readStr) } -func (m ReaderMatcher) String() string { +func (m readerMatcher) String() string { return fmt.Sprintf("reads to %s", m.expect) }