stronger kind tests and validation
This commit is contained in:
+11
-5
@@ -7,11 +7,12 @@ const (
|
||||
KindBuy
|
||||
KindSell
|
||||
KindSplit
|
||||
sentinelKind
|
||||
)
|
||||
|
||||
// String returns a human readable value
|
||||
func (d Kind) String() string {
|
||||
switch d {
|
||||
// String returns a unique string value for Kind k
|
||||
func (k Kind) String() string {
|
||||
switch k {
|
||||
case KindBuy:
|
||||
return "buy"
|
||||
case KindSell:
|
||||
@@ -23,8 +24,13 @@ func (d Kind) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// Is returns true when k equals o
|
||||
// Valid returns true if k is an accepted value for the Kind type
|
||||
func (k Kind) Valid() bool {
|
||||
return k > 0 && k < sentinelKind
|
||||
}
|
||||
|
||||
// Is returns true when k and o are valid and equal.
|
||||
func (k Kind) Is(o any) bool {
|
||||
other, ok := o.(Kind)
|
||||
return ok && k == other
|
||||
return ok && k.Valid() && k == other
|
||||
}
|
||||
|
||||
+80
-45
@@ -1,60 +1,95 @@
|
||||
package internal
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSide_String(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
side Kind
|
||||
want string
|
||||
}{
|
||||
{"buy", KindBuy, "buy"},
|
||||
{"sell", KindSell, "sell"},
|
||||
{"unknown", KindUnknown, "unknown"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.side.String(); got != tt.want {
|
||||
t.Errorf("want Side.String() to be %v but got %v", tt.want, got)
|
||||
const unknown = "unknown"
|
||||
|
||||
seen := make(map[string]Kind, sentinelKind)
|
||||
for k := Kind(1); k < sentinelKind; k++ {
|
||||
t.Run(fmt.Sprintf("Kind %d", k), func(t *testing.T) {
|
||||
str := k.String()
|
||||
|
||||
if other, ok := seen[str]; ok {
|
||||
t.Errorf("want Kind(%d).String to be unique but was a duplicate of Kind(%d)", k, other)
|
||||
} else {
|
||||
seen[str] = k
|
||||
}
|
||||
|
||||
if len(str) == 0 {
|
||||
t.Errorf("want Kind(%d).String to be non-empty", k)
|
||||
}
|
||||
|
||||
if str == unknown {
|
||||
t.Errorf("want Kind(%d).String to be a known value", k)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if KindUnknown.String() != unknown {
|
||||
t.Errorf("want Kind(0) to be unknown")
|
||||
}
|
||||
|
||||
if Kind(sentinelKind).String() != unknown {
|
||||
t.Errorf("want Kind(%d) to be unknown", sentinelKind)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSide_IsBuy(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
side Kind
|
||||
want bool
|
||||
}{
|
||||
{"buy", KindBuy, true},
|
||||
{"sell", KindSell, false},
|
||||
{"unknown", KindUnknown, false},
|
||||
func TestSide_Valid(t *testing.T) {
|
||||
for k := Kind(1); k < sentinelKind; k++ {
|
||||
if !k.Valid() {
|
||||
t.Errorf("want %s(%d) to be valid", k, k)
|
||||
}
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.side.Is(KindBuy); got != tt.want {
|
||||
t.Errorf("want Side.IsBuy() to be %v but got %v", tt.want, got)
|
||||
}
|
||||
})
|
||||
|
||||
if KindUnknown.Valid() {
|
||||
t.Errorf("want Kind(0) to be invalid")
|
||||
}
|
||||
|
||||
if Kind(sentinelKind).Valid() {
|
||||
t.Errorf("want Kind(%d) to be invalid", sentinelKind)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSide_IsSell(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
side Kind
|
||||
want bool
|
||||
}{
|
||||
{"buy", KindBuy, false},
|
||||
{"sell", KindSell, true},
|
||||
{"unknown", KindUnknown, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.side.Is(KindSell); got != tt.want {
|
||||
t.Errorf("want Side.IsSell() to be %v but got %v", tt.want, got)
|
||||
func TestSide_Is(t *testing.T) {
|
||||
t.Run("valid is self", func(t *testing.T) {
|
||||
for k := Kind(1); k < sentinelKind; k++ {
|
||||
if !k.Is(k) {
|
||||
t.Errorf("want Kind(%d).Is(%d) to be true", k, k)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("valid is unknown", func(t *testing.T) {
|
||||
for k := Kind(1); k < sentinelKind; k++ {
|
||||
if k.Is(KindUnknown) {
|
||||
t.Errorf("want Kind(%d).Is(0) to be false", k)
|
||||
}
|
||||
|
||||
if k.Is(sentinelKind) {
|
||||
t.Errorf("want Kind(%d).Is(%d) to be false", k, sentinelKind)
|
||||
}
|
||||
|
||||
if k.Is(struct{}{}) {
|
||||
t.Errorf("want Kind(%d).Is(other type) to be false", k)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("unknown is unknown", func(t *testing.T) {
|
||||
if KindUnknown.Is(KindUnknown) {
|
||||
t.Errorf("want Kind(0).Is(0) to be false")
|
||||
}
|
||||
|
||||
if KindUnknown.Is(sentinelKind) {
|
||||
t.Errorf("want Kind(0).Is(%d) to be false", sentinelKind)
|
||||
}
|
||||
|
||||
if sentinelKind.Is(sentinelKind) {
|
||||
t.Errorf("want Kind(%d).Is(%d) to be false", sentinelKind, sentinelKind)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -132,6 +132,8 @@ func BuildReport(ctx context.Context, reader RecordReader, writer ReportWriter,
|
||||
buysCount++
|
||||
} else if rec.Kind().Is(KindSell) {
|
||||
sellsCount++
|
||||
} else if !rec.Kind().Valid() {
|
||||
return fmt.Errorf("cannot process Kind(%d)", rec.Kind())
|
||||
}
|
||||
|
||||
lastTimestamp = rec.Timestamp()
|
||||
|
||||
Reference in New Issue
Block a user