Add sqldb and set packages
This commit is contained in:
Executable
+74
@@ -0,0 +1,74 @@
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Set is a set of int64.
|
||||
type Set struct {
|
||||
items map[int64]struct{}
|
||||
}
|
||||
|
||||
// New creates a new int64 set.
|
||||
func New(items ...int64) *Set {
|
||||
s := &Set{items: make(map[int64]struct{}, len(items))}
|
||||
s.Add(items...)
|
||||
return s
|
||||
}
|
||||
|
||||
// Add adds given items to the set.
|
||||
func (s *Set) Add(items ...int64) *Set {
|
||||
for _, item := range items {
|
||||
s.items[item] = struct{}{}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Remove delete given items from the set.
|
||||
func (s *Set) Remove(items ...int64) *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 ...int64) 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() []int64 {
|
||||
sl := make([]int64, 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() []int64 {
|
||||
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())
|
||||
}
|
||||
Executable
+116
@@ -0,0 +1,116 @@
|
||||
package impl
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
const (
|
||||
One int64 = 1
|
||||
Two int64 = 2
|
||||
Three int64 = 3
|
||||
Four int64 = 4
|
||||
Five int64 = 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 []int64{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 []int64{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 []int64{One, Two, Three} {
|
||||
if ok := s.Has(item); ok {
|
||||
t.Errorf("Set is expected to not contain item %q", item)
|
||||
}
|
||||
}
|
||||
for _, item := range []int64{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[int64]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 := []int64{One, Two, Three}
|
||||
ignoreOrder := cmpopts.SortSlices(func(a, b int64) 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 := []int64{One, Two, Three}
|
||||
if !cmp.Equal(exp, out) {
|
||||
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user