mirror of https://github.com/dirtbags/moth.git
award now its own package
This commit is contained in:
parent
7b353131e4
commit
a46ae95cb6
|
@ -0,0 +1,87 @@
|
|||
// Package award defines a MOTH award, and provides tools to use them.
|
||||
package award
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// T represents a single award event.
|
||||
type T struct {
|
||||
// Unix epoch time of this event
|
||||
When int64
|
||||
TeamID string
|
||||
Category string
|
||||
Points int
|
||||
}
|
||||
|
||||
// List is a collection of award events.
|
||||
type List []*T
|
||||
|
||||
// Len implements sort.Interface.
|
||||
func (awards List) Len() int {
|
||||
return len(awards)
|
||||
}
|
||||
|
||||
// Less implements sort.Interface.
|
||||
func (awards List) Less(i, j int) bool {
|
||||
return awards[i].When < awards[j].When
|
||||
}
|
||||
|
||||
// Swap implements sort.Interface.
|
||||
func (awards List) Swap(i, j int) {
|
||||
tmp := awards[i]
|
||||
awards[i] = awards[j]
|
||||
awards[j] = tmp
|
||||
}
|
||||
|
||||
// Parse parses a string log entry into an award.T.
|
||||
func Parse(s string) (*T, error) {
|
||||
ret := T{}
|
||||
|
||||
s = strings.TrimSpace(s)
|
||||
|
||||
n, err := fmt.Sscanf(s, "%d %s %s %d", &ret.When, &ret.TeamID, &ret.Category, &ret.Points)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if n != 4 {
|
||||
return nil, fmt.Errorf("Malformed award string: only parsed %d fields", n)
|
||||
}
|
||||
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
// String returns a log entry string for an award.T.
|
||||
func (a *T) String() string {
|
||||
return fmt.Sprintf("%d %s %s %d", a.When, a.TeamID, a.Category, a.Points)
|
||||
}
|
||||
|
||||
// MarshalJSON returns the award event, encoded as a list.
|
||||
func (a *T) MarshalJSON() ([]byte, error) {
|
||||
if a == nil {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
ao := []interface{}{
|
||||
a.When,
|
||||
a.TeamID,
|
||||
a.Category,
|
||||
a.Points,
|
||||
}
|
||||
|
||||
return json.Marshal(ao)
|
||||
}
|
||||
|
||||
// Equal returns true if two award events represent the same award.
|
||||
// Timestamps are ignored in this comparison!
|
||||
func (a *T) Equal(o *T) bool {
|
||||
switch {
|
||||
case a.TeamID != o.TeamID:
|
||||
return false
|
||||
case a.Category != o.Category:
|
||||
return false
|
||||
case a.Points != o.Points:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package award
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAward(t *testing.T) {
|
||||
entry := "1536958399 1a2b3c4d counting 10"
|
||||
a, err := Parse(entry)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if a.TeamID != "1a2b3c4d" {
|
||||
t.Error("TeamID parsed wrong")
|
||||
}
|
||||
if a.Category != "counting" {
|
||||
t.Error("Category parsed wrong")
|
||||
}
|
||||
if a.Points != 10 {
|
||||
t.Error("Points parsed wrong")
|
||||
}
|
||||
|
||||
if a.String() != entry {
|
||||
t.Error("String conversion wonky")
|
||||
}
|
||||
|
||||
b, err := Parse(entry[2:])
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !a.Equal(b) {
|
||||
t.Error("Different timestamp events do not compare equal")
|
||||
}
|
||||
|
||||
c, err := Parse(entry[:len(entry)-1])
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if a.Equal(c) {
|
||||
t.Error("Different pount values compare equal")
|
||||
}
|
||||
|
||||
if ja, err := a.MarshalJSON(); err != nil {
|
||||
t.Error(err)
|
||||
} else if string(ja) != `[1536958399,"1a2b3c4d","counting",10]` {
|
||||
t.Error("JSON wrong")
|
||||
}
|
||||
|
||||
if _, err := Parse("bad bad bad 1"); err == nil {
|
||||
t.Error("Not throwing error on bad timestamp")
|
||||
}
|
||||
if _, err := Parse("1 bad bad bad"); err == nil {
|
||||
t.Error("Not throwing error on bad points")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAwardList(t *testing.T) {
|
||||
a, _ := Parse("1536958399 1a2b3c4d counting 1")
|
||||
b, _ := Parse("1536958400 1a2b3c4d counting 1")
|
||||
c, _ := Parse("1536958300 1a2b3c4d counting 1")
|
||||
list := List{a, b, c}
|
||||
|
||||
if sort.IsSorted(list) {
|
||||
t.Error("Unsorted list thinks it's sorted")
|
||||
}
|
||||
|
||||
sort.Stable(list)
|
||||
if (list[0] != c) || (list[1] != a) || (list[2] != b) {
|
||||
t.Error("Sorting didn't")
|
||||
}
|
||||
|
||||
if !sort.IsSorted(list) {
|
||||
t.Error("Sorted list thinks it isn't")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue