Add sqldb and set packages

This commit is contained in:
2018-06-23 23:46:35 +02:00
parent 0df8b1ec84
commit b06910f223
31 changed files with 2983 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of uint64.
type Set struct {
items map[uint64]struct{}
}
// New creates a new uint64 set.
func New(items ...uint64) *Set {
s := &Set{items: make(map[uint64]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...uint64) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...uint64) *Set {
for _, item := range items {
delete(s.items, item)
}
return s
}
// Has returns true if all the given items are included in the set.
func (s *Set) Has(items ...uint64) bool {
for _, item := range items {
if _, ok := s.items[item]; !ok {
return false
}
}
return true
}
// Len returns the size of the set.
func (s *Set) Len() int {
return len(s.items)
}
// Slice returns items of the set as a slice.
func (s *Set) Slice() []uint64 {
sl := make([]uint64, len(s.items))
i := 0
for item := range s.items {
sl[i] = item
i++
}
return sl
}
// SortedSlice returns items of the set as a slice sorted ascending.
func (s *Set) SortedSlice() []uint64 {
ss := s.Slice()
sort.Slice(ss, func(i, j int) bool {
return ss[i] < ss[j]
})
return ss
}
// String implements fmt.Stringer interface.
func (s *Set) String() string {
return fmt.Sprintf("[%v]", s.Slice())
}
+116
View File
@@ -0,0 +1,116 @@
package impl
import (
"testing"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/google/go-cmp/cmp"
)
const (
One uint64 = 1
Two uint64 = 2
Three uint64 = 3
Four uint64 = 4
Five uint64 = 5
)
func TestNew(t *testing.T) {
s := New(One, Two, Three)
if s == nil {
t.Fatal("Set is nil")
}
if s.Len() != 3 {
t.Errorf("Expected set to contain 3 items, got %d", s.Len())
}
for _, item := range []uint64{One, Two, Three} {
if ok := s.Has(item); !ok {
t.Errorf("Set is expected to contain item %q", item)
}
}
}
func TestAdd(t *testing.T) {
s := New()
if s.Len() != 0 {
t.Errorf("Expected set to be empty, got %d items", s.Len())
}
s.Add(One)
s.Add(Two, Three)
for _, item := range []uint64{One, Two, Three} {
if ok := s.Has(item); !ok {
t.Errorf("Set is expected to contain item %q", item)
}
}
}
func TestRemove(t *testing.T) {
s := New(One, Two, Three, Four, Five)
s.Remove(One, Two)
s.Remove(Three)
if s.Len() != 2 {
t.Errorf("Expected set to contain 2 items, got %d", s.Len())
}
for _, item := range []uint64{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []uint64{Four, Five} {
if ok := s.Has(item); !ok {
t.Errorf("Set is expected to contain item %q", item)
}
}
}
func TestHas(t *testing.T) {
s := New(One, Two)
table := map[uint64]bool{
One: true,
Two: true,
Three: false,
Four: false,
Five: false,
}
for v, exp := range table {
if res := s.Has(v); res != exp {
t.Errorf("Item: %v, In: %v, Expected: %v", v, res, exp)
}
}
}
func TestLen(t *testing.T) {
table := map[*Set]int{
New(): 0,
New(One): 1,
New(Two, Three): 2,
New(One, Two, Three, Four, Five, Five): 5,
}
for s, exp := range table {
if res := s.Len(); res != exp {
t.Errorf("Expected set %s to have length %d, got %d", s, exp, res)
}
}
}
func TestSlice(t *testing.T) {
s := New(One, Two, Three)
out := s.Slice()
exp := []uint64{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b uint64) bool {
return a < b
})
if !cmp.Equal(exp, out, ignoreOrder) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}
func TestSortedSlice(t *testing.T) {
s := New(One, Two, Three)
out := s.SortedSlice()
exp := []uint64{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}