Skip to content

Commit

Permalink
Add puppy interface functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Cameron Schafer committed Jun 21, 2019
1 parent c25afb1 commit 308fea3
Show file tree
Hide file tree
Showing 2 changed files with 254 additions and 0 deletions.
122 changes: 122 additions & 0 deletions 06_puppy/CameronSchafer/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package main

import (
"fmt"
"io"
"os"
"sync" //https://golang.org/pkg/sync/#Map
)

var out io.Writer = os.Stdout

type Puppy struct {
pid int
breed string
colour string
value string
}

type MapStore struct {
store map[int]Puppy
}

type SyncStore struct {
store sync.Map
}

type Storer interface {
CreatePuppy(*Puppy) int
ReadPuppy(int) *Puppy
UpdatePuppy(*Puppy)
DeletePuppy(int)
}

func (m *MapStore) CreatePuppy(p *Puppy) int {
m.store[p.pid] = *p
return p.pid
}
func (m *MapStore) ReadPuppy(pid int) *Puppy {
pup, ok := m.store[pid]
if ok {
return &pup
}
return nil
}
func (m *MapStore) UpdatePuppy(p *Puppy) {
m.store[p.pid] = *p
}
func (m *MapStore) DeletePuppy(pid int) {
delete(m.store, pid)
}

func (s *SyncStore) CreatePuppy(p *Puppy) int {
s.store.Store(p.pid, p)
return p.pid
}
func (s *SyncStore) ReadPuppy(pid int) *Puppy {
pup, ok := s.store.Load(pid)
if ok {
return pup.(*Puppy)
}
return nil
}
func (s *SyncStore) UpdatePuppy(p *Puppy) {
s.store.Store(p.pid, p)
}
func (s *SyncStore) DeletePuppy(pid int) {
s.store.Delete(pid)
}

// using the map store + methods
func usingNormMap(pups []Puppy) {
// initialise the map store
var puppyMS Storer = &MapStore{store: make(map[int]Puppy)}
for _, n := range pups {
pup := n
puppyMS.CreatePuppy(&pup)
}
if p := puppyMS.ReadPuppy(pups[1].pid); p != nil {
fmt.Fprintln(out, *p)
}

upDog := pups[0]
upDog.colour = "red"
puppyMS.UpdatePuppy(&upDog)
puppyMS.DeletePuppy(pups[1].pid)

fmt.Fprintln(out, puppyMS)
}

// using the sync map store + methods
func usingSyncMap(pups []Puppy) {
// initialise the sync store
var puppySS Storer = &SyncStore{}
for _, n := range pups {
pup := n
puppySS.CreatePuppy(&pup)
}
if p := puppySS.ReadPuppy(pups[1].pid); p != nil {
fmt.Fprintln(out, *p)
}

upDog := pups[0]
upDog.colour = "red"
puppySS.UpdatePuppy(&upDog)
puppySS.DeletePuppy(pups[1].pid)

for _, pup := range pups {
if p := puppySS.ReadPuppy(pup.pid); p != nil {
fmt.Fprintln(out, *p)
}
}
}

func main() {
pups := []Puppy{
{99, "poodle", "blue", "$10.99"},
{100, "lab", "orange", "$9.99"},
{101, "cat", "striped", "$99.99"},
}
usingNormMap(pups)
usingSyncMap(pups)
}
132 changes: 132 additions & 0 deletions 06_puppy/CameronSchafer/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package main

import (
"bytes"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)

type StorerTestSuite struct {
suite.Suite
storer Storer
}

func (suite StorerTestSuite) SetupTest() {
suite.storer.CreatePuppy(&Puppy{1, "catdog", "brown + spots", "9.99"})
suite.storer.CreatePuppy(&Puppy{2, "non-cube", "yellowy-blue", "3.50"})
}

func (suite StorerTestSuite) TestCreate() {
suite.storer.CreatePuppy(&Puppy{3, "boxer", "yellowish-yellow", "99999.01"})
pup := suite.storer.ReadPuppy(3)
suite.Equal(3, pup.pid)
suite.Equal("boxer", pup.breed)
suite.Equal("yellowish-yellow", pup.colour)
suite.Equal("99999.01", pup.value)
}

func (suite StorerTestSuite) TestRead() {
pup := suite.storer.ReadPuppy(1)
suite.Equal(1, pup.pid)
suite.Equal("catdog", pup.breed)
suite.Equal("brown + spots", pup.colour)
suite.Equal("9.99", pup.value)
}

func (suite StorerTestSuite) TestUpdate() {
suite.storer.UpdatePuppy(&Puppy{2, "cube", "bluey-yellow", "1.75"})
pup := suite.storer.ReadPuppy(2)
suite.Equal(2, pup.pid)
suite.Equal("cube", pup.breed)
suite.Equal("bluey-yellow", pup.colour)
suite.Equal("1.75", pup.value)
}

func (suite StorerTestSuite) TestDelete() {
suite.storer.DeletePuppy(1)
pup1 := suite.storer.ReadPuppy(1)
pup2 := suite.storer.ReadPuppy(2)
suite.Nil(pup1)
suite.Equal(2, pup2.pid)
suite.Equal("non-cube", pup2.breed)
suite.Equal("yellowy-blue", pup2.colour)
suite.Equal("3.50", pup2.value)
}

func TestMapStorer(t *testing.T) {
store := StorerTestSuite{
storer: &MapStore{store: make(map[int]Puppy)},
}
suite.Run(t, &store)
}

func TestSyncStorer(t *testing.T) {
store := StorerTestSuite{storer: &SyncStore{}}
suite.Run(t, &store)
}

// main() test
func TestMainOutput(t *testing.T) {
var buf bytes.Buffer
out = &buf

main()
expected := `{100 lab orange $9.99}
&{map[99:{99 poodle red $10.99} 101:{101 cat striped $99.99}]}
{100 lab orange $9.99}
{99 poodle red $10.99}
{101 cat striped $99.99}
`
actual := buf.String()

assert.Equalf(t, expected, actual,
"Unexpected output in main()\nexpected: %q\nactual: %q",
expected, actual)

}

// normalMap()
func TestNormalMap(t *testing.T) {
var buf bytes.Buffer
out = &buf

pups := []Puppy{
{99, "poodle", "blue", "$10.99"},
{100, "lab", "orange", "$9.99"},
{101, "cat", "striped", "$99.99"},
}
usingNormMap(pups)

expected := `{100 lab orange $9.99}
&{map[99:{99 poodle red $10.99} 101:{101 cat striped $99.99}]}
`
actual := buf.String()

assert.Equalf(t, expected, actual,
"Unexpected output in main()\nexpected: %q\nactual: %q",
expected, actual)
}

// syncMap()
func TestSyncMap(t *testing.T) {
var buf bytes.Buffer
out = &buf

pups := []Puppy{
{99, "poodle", "blue", "$10.99"},
{100, "lab", "orange", "$9.99"},
{101, "cat", "striped", "$99.99"},
}
usingSyncMap(pups)
expected := `{100 lab orange $9.99}
{99 poodle red $10.99}
{101 cat striped $99.99}
`
actual := buf.String()

assert.Equalf(t, expected, actual,
"Unexpected output in main()\nexpected: %q\nactual: %q",
expected, actual)
}

0 comments on commit 308fea3

Please sign in to comment.