-
Notifications
You must be signed in to change notification settings - Fork 164
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Cameron Schafer
committed
Jun 21, 2019
1 parent
c25afb1
commit 308fea3
Showing
2 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |