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
+119
View File
@@ -0,0 +1,119 @@
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path"
"reflect"
"strings"
)
type genericType struct {
name string
testVals []string
}
var types = []genericType{
// Int
{name: reflect.Int.String(), testVals: []string{"1", "2", "3", "4", "5"}},
{name: reflect.Int8.String(), testVals: []string{"1", "2", "3", "4", "5"}},
{name: reflect.Int16.String(), testVals: []string{"1", "2", "3", "4", "5"}},
{name: reflect.Int32.String(), testVals: []string{"1", "2", "3", "4", "5"}},
{name: reflect.Int64.String(), testVals: []string{"1", "2", "3", "4", "5"}},
// Uint
{name: reflect.Uint.String(), testVals: []string{"1", "2", "3", "4", "5"}},
{name: reflect.Uint8.String(), testVals: []string{"1", "2", "3", "4", "5"}},
{name: reflect.Uint16.String(), testVals: []string{"1", "2", "3", "4", "5"}},
{name: reflect.Uint32.String(), testVals: []string{"1", "2", "3", "4", "5"}},
{name: reflect.Uint64.String(), testVals: []string{"1", "2", "3", "4", "5"}},
// String
{name: reflect.String.String(), testVals: []string{`"1"`, `"2"`, `"3"`, `"4"`, `"5"`}},
}
func main() {
tplDir := flag.String("tpl", "", "Path to template directory")
destDir := flag.String("dest", "", "Path to destination directory")
flag.Parse()
if *tplDir == "" {
log.Println("Template directory is not specified")
flag.Usage()
os.Exit(1)
}
if *destDir == "" {
log.Println("Destination directory is not specified")
flag.Usage()
os.Exit(1)
}
implSource, err := ioutil.ReadFile(path.Join(*tplDir, "set.go"))
if err != nil {
log.Fatalf("Failed to read source file at %s: %v", path.Join(*tplDir, "set.go"), err)
}
testSource, err := ioutil.ReadFile(path.Join(*tplDir, "set_test.go"))
if err != nil {
log.Fatalf("Failed to read test file at %s: %v", path.Join(*tplDir, "set_test.go"), err)
}
for _, typ := range types {
log.Printf("Generating package for type %s\n", typ.name)
err := generate(*destDir, implSource, testSource, typ)
if err != nil {
log.Fatalf("Failed to generate a package for type %s: %v", typ.name, err)
}
}
err = gofmt(*destDir)
if err != nil {
log.Fatalf("Formatting failed: %v", err)
}
log.Println("Set packages were successfully generated")
}
func generate(destDir string, implSource, testSource []byte, typ genericType) error {
pkgDir := path.Join(destDir, fmt.Sprintf("set%s", typ.name))
err := os.RemoveAll(pkgDir)
if err != nil && !os.IsNotExist(err) {
return err
}
err = os.Mkdir(pkgDir, 0777)
if err != nil {
return err
}
err = ioutil.WriteFile(path.Join(pkgDir, "set.go"), renderBytes(implSource, typ), 0755)
if err != nil {
return err
}
err = ioutil.WriteFile(path.Join(pkgDir, "set_test.go"), renderBytes(testSource, typ), 0755)
return err
}
func renderBytes(src []byte, typ genericType) []byte {
return []byte(render(string(src), typ))
}
func render(src string, typ genericType) string {
const genericTypeName = "TypeName"
// Replace test constants
src = strings.Replace(src, "One TypeName = 1", "One TypeName = "+typ.testVals[0], 1)
src = strings.Replace(src, "Two TypeName = 2", "Two TypeName = "+typ.testVals[1], 1)
src = strings.Replace(src, "Three TypeName = 3", "Three TypeName = "+typ.testVals[2], 1)
src = strings.Replace(src, "Four TypeName = 4", "Four TypeName = "+typ.testVals[3], 1)
src = strings.Replace(src, "Five TypeName = 5", "Five TypeName = "+typ.testVals[4], 1)
// Replace the type name
src = strings.Replace(src, genericTypeName, typ.name, -1)
return src
}
func gofmt(dir string) error {
out, err := exec.Command("gofmt", "-w", "-l", dir).CombinedOutput()
if err != nil {
log.Println("gofmt returned:", string(out))
}
return err
}
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of TypeName.
type Set struct {
items map[TypeName]struct{}
}
// New creates a new TypeName set.
func New(items ...TypeName) *Set {
s := &Set{items: make(map[TypeName]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...TypeName) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...TypeName) *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 ...TypeName) 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() []TypeName {
sl := make([]TypeName, 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() []TypeName {
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())
}
+114
View File
@@ -0,0 +1,114 @@
package impl
import (
"testing"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/google/go-cmp/cmp"
)
const (
One TypeName = 1
Two TypeName = 2
Three TypeName = 3
Four TypeName = 4
Five TypeName = 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 []TypeName{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 []TypeName{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 []TypeName{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []TypeName{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[TypeName]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 := []TypeName{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b TypeName) 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 := []TypeName{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}
+4
View File
@@ -0,0 +1,4 @@
package impl
// TypeName is a type placeholder.
type TypeName int
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of int.
type Set struct {
items map[int]struct{}
}
// New creates a new int set.
func New(items ...int) *Set {
s := &Set{items: make(map[int]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...int) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...int) *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 ...int) 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() []int {
sl := make([]int, 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() []int {
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 int = 1
Two int = 2
Three int = 3
Four int = 4
Five int = 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 []int{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 []int{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 []int{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []int{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[int]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 := []int{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b int) 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 := []int{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of int16.
type Set struct {
items map[int16]struct{}
}
// New creates a new int16 set.
func New(items ...int16) *Set {
s := &Set{items: make(map[int16]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...int16) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...int16) *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 ...int16) 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() []int16 {
sl := make([]int16, 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() []int16 {
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 int16 = 1
Two int16 = 2
Three int16 = 3
Four int16 = 4
Five int16 = 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 []int16{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 []int16{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 []int16{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []int16{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[int16]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 := []int16{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b int16) 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 := []int16{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of int32.
type Set struct {
items map[int32]struct{}
}
// New creates a new int32 set.
func New(items ...int32) *Set {
s := &Set{items: make(map[int32]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...int32) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...int32) *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 ...int32) 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() []int32 {
sl := make([]int32, 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() []int32 {
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 int32 = 1
Two int32 = 2
Three int32 = 3
Four int32 = 4
Five int32 = 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 []int32{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 []int32{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 []int32{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []int32{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[int32]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 := []int32{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b int32) 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 := []int32{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}
+74
View File
@@ -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())
}
+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 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))
}
}
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of int8.
type Set struct {
items map[int8]struct{}
}
// New creates a new int8 set.
func New(items ...int8) *Set {
s := &Set{items: make(map[int8]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...int8) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...int8) *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 ...int8) 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() []int8 {
sl := make([]int8, 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() []int8 {
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 int8 = 1
Two int8 = 2
Three int8 = 3
Four int8 = 4
Five int8 = 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 []int8{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 []int8{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 []int8{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []int8{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[int8]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 := []int8{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b int8) 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 := []int8{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of string.
type Set struct {
items map[string]struct{}
}
// New creates a new string set.
func New(items ...string) *Set {
s := &Set{items: make(map[string]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...string) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...string) *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 ...string) 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() []string {
sl := make([]string, 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() []string {
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 string = "1"
Two string = "2"
Three string = "3"
Four string = "4"
Five string = "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 []string{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 []string{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 []string{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []string{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[string]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 := []string{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b string) 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 := []string{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of uint.
type Set struct {
items map[uint]struct{}
}
// New creates a new uint set.
func New(items ...uint) *Set {
s := &Set{items: make(map[uint]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...uint) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...uint) *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 ...uint) 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() []uint {
sl := make([]uint, 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() []uint {
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 uint = 1
Two uint = 2
Three uint = 3
Four uint = 4
Five uint = 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 []uint{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 []uint{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 []uint{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []uint{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[uint]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 := []uint{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b uint) 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 := []uint{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of uint16.
type Set struct {
items map[uint16]struct{}
}
// New creates a new uint16 set.
func New(items ...uint16) *Set {
s := &Set{items: make(map[uint16]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...uint16) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...uint16) *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 ...uint16) 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() []uint16 {
sl := make([]uint16, 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() []uint16 {
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 uint16 = 1
Two uint16 = 2
Three uint16 = 3
Four uint16 = 4
Five uint16 = 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 []uint16{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 []uint16{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 []uint16{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []uint16{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[uint16]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 := []uint16{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b uint16) 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 := []uint16{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of uint32.
type Set struct {
items map[uint32]struct{}
}
// New creates a new uint32 set.
func New(items ...uint32) *Set {
s := &Set{items: make(map[uint32]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...uint32) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...uint32) *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 ...uint32) 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() []uint32 {
sl := make([]uint32, 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() []uint32 {
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 uint32 = 1
Two uint32 = 2
Three uint32 = 3
Four uint32 = 4
Five uint32 = 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 []uint32{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 []uint32{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 []uint32{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []uint32{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[uint32]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 := []uint32{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b uint32) 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 := []uint32{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}
+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))
}
}
+74
View File
@@ -0,0 +1,74 @@
package impl
import (
"fmt"
"sort"
)
// Set is a set of uint8.
type Set struct {
items map[uint8]struct{}
}
// New creates a new uint8 set.
func New(items ...uint8) *Set {
s := &Set{items: make(map[uint8]struct{}, len(items))}
s.Add(items...)
return s
}
// Add adds given items to the set.
func (s *Set) Add(items ...uint8) *Set {
for _, item := range items {
s.items[item] = struct{}{}
}
return s
}
// Remove delete given items from the set.
func (s *Set) Remove(items ...uint8) *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 ...uint8) 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() []uint8 {
sl := make([]uint8, 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() []uint8 {
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 uint8 = 1
Two uint8 = 2
Three uint8 = 3
Four uint8 = 4
Five uint8 = 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 []uint8{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 []uint8{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 []uint8{One, Two, Three} {
if ok := s.Has(item); ok {
t.Errorf("Set is expected to not contain item %q", item)
}
}
for _, item := range []uint8{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[uint8]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 := []uint8{One, Two, Three}
ignoreOrder := cmpopts.SortSlices(func(a, b uint8) 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 := []uint8{One, Two, Three}
if !cmp.Equal(exp, out) {
t.Errorf("Retured slice does not match: %s", cmp.Diff(exp, out))
}
}