From 011ea39fc1363c68abacd1709fc73f795f721fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oscar=20S=C3=B6derlund?= Date: Wed, 24 Jul 2019 21:07:03 +0200 Subject: [PATCH] Initial clock and mock Gomock generated code checked in, allows reuse of our existing pattern across many repositories. --- .gitignore | 2 + Makefile | 54 ++++++++++++++++ go.mod | 8 +++ go.sum | 11 ++++ pkg/clock/clock.go | 32 ++++++++++ pkg/clock/system.go | 41 ++++++++++++ pkg/mockclock/clock.go | 141 +++++++++++++++++++++++++++++++++++++++++ tools.go | 5 ++ 8 files changed, 294 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 go.mod create mode 100644 go.sum create mode 100644 pkg/clock/clock.go create mode 100644 pkg/clock/system.go create mode 100644 pkg/mockclock/clock.go create mode 100644 tools.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f6bba46 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +.gobincache diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fd5d3fd --- /dev/null +++ b/Makefile @@ -0,0 +1,54 @@ +# all: run a complete build +all: \ + markdown-lint \ + mocks \ + go-lint \ + go-review \ + go-mod-tidy \ + git-verify-nodiff \ + git-verify-submodules + +export GO111MODULE := on + +# clean: remove all generated build files +.PHONY: clean +clean: + rm -rf build + +.PHONY: build +build: + @git submodule update --init --recursive $@ + +include build/rules.mk +build/rules.mk: build + @# included in submodule: build + +# markdown-lint: lint Markdown files +.PHONY: markdown-lint +markdown-lint: $(PRETTIER) + $(PRETTIER) --check **/*.md --parser markdown + +# go-mod-tidy: update Go module files +.PHONY: go-mod-tidy +go-mod-tidy: + go mod tidy -v + +# go-lint: lint Go files +.PHONY: go-lint +go-lint: $(GOLANGCI_LINT) + $(GOLANGCI_LINT) run --enable-all + +# go-review: review Go files +.PHONY: go-review +go-review: $(GOREVIEW) + $(GOREVIEW) -c 1 ./... + +# mocks: generate Go mocks +.PHONY: mocks +mocks: pkg/mockclock/clock.go + +pkg/mockclock/clock.go: pkg/clock/clock.go $(GOBIN) + $(GOBIN) -m -run github.com/golang/mock/mockgen \ + -destination $@ \ + -package mockclock \ + github.com/einride/clock-go/pkg/clock Clock,Ticker diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9439246 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/einride/clock-go + +go 1.12 + +require ( + github.com/golang/mock v1.3.1 + github.com/golang/protobuf v1.3.2 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..453b18d --- /dev/null +++ b/go.sum @@ -0,0 +1,11 @@ +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262 h1:qsl9y/CJx34tuA7QCPNp86JNJe4spst6Ff8MjvPUdPg= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= diff --git a/pkg/clock/clock.go b/pkg/clock/clock.go new file mode 100644 index 0000000..54b3647 --- /dev/null +++ b/pkg/clock/clock.go @@ -0,0 +1,32 @@ +// Package clock provides primitives for mocking time. +package clock + +import ( + "time" + + "github.com/golang/protobuf/ptypes/timestamp" +) + +// Clock provides capabilities from the time standard library package. +type Clock interface { + // After waits for the duration to elapse and then sends the current time on the returned channel. + After(duration time.Duration) <-chan time.Time + + // NewTicker returns a new Ticker. + NewTicker(d time.Duration) Ticker + + // Now returns the current local time. + Now() time.Time + + // NowProto returns a new Protobuf timestamp representing the current local time. + NowProto() *timestamp.Timestamp +} + +// Ticker wraps the time.Ticker class. +type Ticker interface { + // C returns the channel on which the ticks are delivered. + C() <-chan time.Time + + // Stop the Ticker. + Stop() +} diff --git a/pkg/clock/system.go b/pkg/clock/system.go new file mode 100644 index 0000000..2d33888 --- /dev/null +++ b/pkg/clock/system.go @@ -0,0 +1,41 @@ +package clock + +import ( + "time" + + "github.com/golang/protobuf/ptypes" + "github.com/golang/protobuf/ptypes/timestamp" +) + +// System returns a Clock implementation that delegate to the time package. +func System() Clock { + return &systemClock{} +} + +type systemClock struct{} + +var _ Clock = &systemClock{} + +func (c systemClock) After(d time.Duration) <-chan time.Time { + return time.After(d) +} + +func (c systemClock) NowProto() *timestamp.Timestamp { + return ptypes.TimestampNow() +} + +func (c systemClock) NewTicker(d time.Duration) Ticker { + return &systemTicker{Ticker: *time.NewTicker(d)} +} + +func (c systemClock) Now() time.Time { + return time.Now() +} + +type systemTicker struct { + time.Ticker +} + +func (t systemTicker) C() <-chan time.Time { + return t.Ticker.C +} diff --git a/pkg/mockclock/clock.go b/pkg/mockclock/clock.go new file mode 100644 index 0000000..55e1c88 --- /dev/null +++ b/pkg/mockclock/clock.go @@ -0,0 +1,141 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/einride/clock-go/pkg/clock (interfaces: Clock,Ticker) + +// Package mockclock is a generated GoMock package. +package mockclock + +import ( + clock "github.com/einride/clock-go/pkg/clock" + gomock "github.com/golang/mock/gomock" + timestamp "github.com/golang/protobuf/ptypes/timestamp" + reflect "reflect" + time "time" +) + +// MockClock is a mock of Clock interface +type MockClock struct { + ctrl *gomock.Controller + recorder *MockClockMockRecorder +} + +// MockClockMockRecorder is the mock recorder for MockClock +type MockClockMockRecorder struct { + mock *MockClock +} + +// NewMockClock creates a new mock instance +func NewMockClock(ctrl *gomock.Controller) *MockClock { + mock := &MockClock{ctrl: ctrl} + mock.recorder = &MockClockMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockClock) EXPECT() *MockClockMockRecorder { + return m.recorder +} + +// After mocks base method +func (m *MockClock) After(arg0 time.Duration) <-chan time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "After", arg0) + ret0, _ := ret[0].(<-chan time.Time) + return ret0 +} + +// After indicates an expected call of After +func (mr *MockClockMockRecorder) After(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "After", reflect.TypeOf((*MockClock)(nil).After), arg0) +} + +// NewTicker mocks base method +func (m *MockClock) NewTicker(arg0 time.Duration) clock.Ticker { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewTicker", arg0) + ret0, _ := ret[0].(clock.Ticker) + return ret0 +} + +// NewTicker indicates an expected call of NewTicker +func (mr *MockClockMockRecorder) NewTicker(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewTicker", reflect.TypeOf((*MockClock)(nil).NewTicker), arg0) +} + +// Now mocks base method +func (m *MockClock) Now() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Now") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// Now indicates an expected call of Now +func (mr *MockClockMockRecorder) Now() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Now", reflect.TypeOf((*MockClock)(nil).Now)) +} + +// NowProto mocks base method +func (m *MockClock) NowProto() *timestamp.Timestamp { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NowProto") + ret0, _ := ret[0].(*timestamp.Timestamp) + return ret0 +} + +// NowProto indicates an expected call of NowProto +func (mr *MockClockMockRecorder) NowProto() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NowProto", reflect.TypeOf((*MockClock)(nil).NowProto)) +} + +// MockTicker is a mock of Ticker interface +type MockTicker struct { + ctrl *gomock.Controller + recorder *MockTickerMockRecorder +} + +// MockTickerMockRecorder is the mock recorder for MockTicker +type MockTickerMockRecorder struct { + mock *MockTicker +} + +// NewMockTicker creates a new mock instance +func NewMockTicker(ctrl *gomock.Controller) *MockTicker { + mock := &MockTicker{ctrl: ctrl} + mock.recorder = &MockTickerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockTicker) EXPECT() *MockTickerMockRecorder { + return m.recorder +} + +// C mocks base method +func (m *MockTicker) C() <-chan time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "C") + ret0, _ := ret[0].(<-chan time.Time) + return ret0 +} + +// C indicates an expected call of C +func (mr *MockTickerMockRecorder) C() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "C", reflect.TypeOf((*MockTicker)(nil).C)) +} + +// Stop mocks base method +func (m *MockTicker) Stop() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Stop") +} + +// Stop indicates an expected call of Stop +func (mr *MockTickerMockRecorder) Stop() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockTicker)(nil).Stop)) +} diff --git a/tools.go b/tools.go new file mode 100644 index 0000000..43976e3 --- /dev/null +++ b/tools.go @@ -0,0 +1,5 @@ +// +build tools + +package tools + +import _ "github.com/golang/mock/mockgen"