diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index cae9b02..b7d0dc7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,4 +10,4 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v2 with: - version: v1.46.2 + version: v1.55.2 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e3a8193 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +.PHONY: help lint test doc +.DEFAULT_GOAL := help + +help: + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +pre-push: lint test ## Run golang lint and test + +lint: ## Run golang lint using docker + go mod download + docker run --rm \ + -v ${GOPATH}/pkg/mod:/go/pkg/mod \ + -v ${PWD}:/app \ + -w /app \ + golangci/golangci-lint:v1.55.2 \ + golangci-lint run -v --modules-download-mode=readonly + +test: ## Run tests + go test ./... + +doc: ## Run doc server using docker + @echo "Doc server runs on http://127.0.0.1:6060" + docker run --rm \ + -p 127.0.0.1:6060:6060 \ + -v ${PWD}:/go/src/github.com/evsamsonov/trading-timeseries \ + -w /go/src/github.com/evsamsonov/trading-timeseries \ + golang:latest \ + bash -c "go install golang.org/x/tools/cmd/godoc@latest && /go/bin/godoc -http=:6060" diff --git a/tickseries/tick_series.go b/tickseries/tick_series.go index 3e57014..ea1497c 100644 --- a/tickseries/tick_series.go +++ b/tickseries/tick_series.go @@ -12,16 +12,31 @@ var ( // TickSeries represents TickSeries of trading ticks type TickSeries struct { - ticks []*Tick - ids map[int64]struct{} + ticks []*Tick + ids map[int64]struct{} + allowZeroID bool +} + +type Option func(*TickSeries) + +// WithAllowZeroIDOption returns Option which sets allowZeroID. +// The default allowZeroID is false +func WithAllowZeroIDOption(allowZeroID bool) Option { + return func(ts *TickSeries) { + ts.allowZeroID = allowZeroID + } } // New creates and returns new TickSeries -func New() *TickSeries { - return &TickSeries{ +func New(opts ...Option) *TickSeries { + ts := &TickSeries{ ticks: make([]*Tick, 0), ids: make(map[int64]struct{}), } + for _, opt := range opts { + opt(ts) + } + return ts } // Add adds a trading tick to the TickSeries. It allows to add @@ -32,8 +47,10 @@ func (t *TickSeries) Add(tick *Tick) error { return ErrCannotBeNil } - if _, ok := t.ids[tick.ID]; ok { - return ErrAlreadyExist + if !t.allowZeroID { + if _, ok := t.ids[tick.ID]; ok { + return ErrAlreadyExist + } } last := t.Last() diff --git a/tickseries/tick_series_test.go b/tickseries/tick_series_test.go index 28f5a0a..bac8fcd 100644 --- a/tickseries/tick_series_test.go +++ b/tickseries/tick_series_test.go @@ -45,6 +45,14 @@ func TestTickSeries_Add(t *testing.T) { tick3.Time = time.Unix(2, 0) assert.Equal(t, nil, tickSeries.Add(tick3)) }) + + t.Run("zero id", func(t *testing.T) { + tickSeries := New(WithAllowZeroIDOption(true)) + tick1 := NewTick(1) + tick1.ID = 0 + tick1.Time = time.Unix(1, 0) + assert.Equal(t, nil, tickSeries.Add(tick1)) + }) } func TestTickSeries_Tick(t *testing.T) {