Initial commit
This commit is contained in:
6
pkg/collection/iterator.go
Normal file
6
pkg/collection/iterator.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package collection
|
||||
|
||||
type Iterator[E any] interface {
|
||||
HasNext() bool
|
||||
Next() E
|
||||
}
|
||||
49
pkg/collection/stack.go
Normal file
49
pkg/collection/stack.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package collection
|
||||
|
||||
import "fmt"
|
||||
|
||||
var (
|
||||
// ErrEmptyStack is error when you have an empty stack structure
|
||||
ErrEmptyStack = fmt.Errorf("this stack is empty")
|
||||
)
|
||||
|
||||
// Stack is an structure with method for handle underlying slice as a stack.
|
||||
type Stack[E any] struct {
|
||||
items []E
|
||||
}
|
||||
|
||||
// Size returns the number of items in the stack.
|
||||
func (s *Stack[E]) Size() int {
|
||||
return len(s.items)
|
||||
}
|
||||
|
||||
// Empty returns true if the stack is empty, otherwise false.
|
||||
func (s *Stack[E]) Empty() bool {
|
||||
return s.Size() == 0
|
||||
}
|
||||
|
||||
// Top get first item in the stack structure, but
|
||||
// if stack is empty well this method return ErrEmptyStack error.
|
||||
func (s *Stack[E]) Top() (E, error) {
|
||||
if s.Empty() {
|
||||
return *new(E), ErrEmptyStack
|
||||
}
|
||||
return s.items[s.Size()-1], nil
|
||||
}
|
||||
|
||||
// Pop get and remove first item in the stack structure, but
|
||||
// if stack is empty well this method return ErrEmptyStack error.
|
||||
func (s *Stack[E]) Pop() (E, error) {
|
||||
item, err := s.Top()
|
||||
if err != nil {
|
||||
return *new(E), err
|
||||
}
|
||||
s.items = s.items[:len(s.items)-1]
|
||||
return item, nil
|
||||
}
|
||||
|
||||
// Push adds an item to the top of the stack.
|
||||
func (s *Stack[E]) Push(item E) error {
|
||||
s.items = append(s.items, item)
|
||||
return nil
|
||||
}
|
||||
99
pkg/collection/stack_test.go
Normal file
99
pkg/collection/stack_test.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package collection_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"asd.me/pkg/collection"
|
||||
)
|
||||
|
||||
type pair struct {
|
||||
value int
|
||||
err error
|
||||
}
|
||||
|
||||
var staticTests = []struct {
|
||||
description string
|
||||
input *collection.Stack[int]
|
||||
empty bool
|
||||
size int
|
||||
top pair
|
||||
}{
|
||||
{"empty stack", newStack([]int{}), true, 0, pair{0, collection.ErrEmptyStack}},
|
||||
{"stack with items", newStack([]int{1, 2, 3}), false, 3, pair{3, nil}},
|
||||
}
|
||||
|
||||
var popTests = []struct {
|
||||
description string
|
||||
input *collection.Stack[int]
|
||||
item pair
|
||||
}{
|
||||
{"empty stack pop item", newStack([]int{}), pair{0, collection.ErrEmptyStack}},
|
||||
{"stack with items pop item", newStack([]int{1, 2, 3}), pair{3, nil}},
|
||||
}
|
||||
|
||||
var pushTests = []struct {
|
||||
description string
|
||||
items []int
|
||||
}{
|
||||
{"zero item pushed", []int{}},
|
||||
{"one item pushed", []int{1}},
|
||||
{"five item pushed", []int{1, 2, 3, 4, 5}},
|
||||
}
|
||||
|
||||
func TestStackStatus(t *testing.T) {
|
||||
for i, tt := range staticTests {
|
||||
t.Logf("Test %v: %s\n", i, tt.description)
|
||||
|
||||
stack := tt.input
|
||||
if tt.empty != stack.Empty() {
|
||||
t.Errorf("stack empty %v, want %v\n", stack.Empty(), tt.empty)
|
||||
}
|
||||
|
||||
if tt.size != stack.Size() {
|
||||
t.Errorf("stack size %v, want %v\n", stack.Size(), tt.size)
|
||||
}
|
||||
|
||||
value, err := stack.Top()
|
||||
if tt.top.err != nil && tt.top.err != err {
|
||||
t.Errorf("stack top is (%v, %v), want (%v, %v)\n", value, err, tt.top.value, tt.top.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPop(t *testing.T) {
|
||||
for i, tt := range popTests {
|
||||
t.Logf("Test %v: %s\n", i, tt.description)
|
||||
|
||||
result, err := tt.input.Pop()
|
||||
if result != tt.item.value {
|
||||
t.Errorf("found result: %v, want %v\n", result, tt.item.value)
|
||||
}
|
||||
|
||||
if err != tt.item.err {
|
||||
t.Errorf("found error: %v, want %v\n", err, tt.item.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPush(t *testing.T) {
|
||||
for i, tt := range pushTests {
|
||||
t.Logf("Test %v: %s\n", i, tt.description)
|
||||
|
||||
stack := &collection.Stack[int]{}
|
||||
for _, item := range tt.items {
|
||||
stack.Push(item)
|
||||
}
|
||||
|
||||
if stack.Size() != len(tt.items) {
|
||||
t.Errorf("stack size %v, want %v\n", stack.Size(), len(tt.items))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newStack(slice []int) *collection.Stack[int] {
|
||||
stack := &collection.Stack[int]{}
|
||||
for _, x := range slice {
|
||||
stack.Push(x)
|
||||
}
|
||||
return stack
|
||||
}
|
||||
Reference in New Issue
Block a user