diff --git a/06_puppy/patrickmarabeas/main.go b/06_puppy/patrickmarabeas/main.go new file mode 100644 index 000000000..790580777 --- /dev/null +++ b/06_puppy/patrickmarabeas/main.go @@ -0,0 +1,5 @@ +package main + +func main() { + +} diff --git a/06_puppy/patrickmarabeas/main_test.go b/06_puppy/patrickmarabeas/main_test.go new file mode 100644 index 000000000..c98b5b046 --- /dev/null +++ b/06_puppy/patrickmarabeas/main_test.go @@ -0,0 +1,25 @@ +package main + +import ( + "bytes" + "io" + "os" + "testing" +) + +var out io.Writer = os.Stdout + +func TestMainOutput(t *testing.T) { + var buf bytes.Buffer + out = &buf + + main() + + expected := "" + + got := buf.String() + + if expected != got { + t.Errorf("\nExpected: %s\nGot: %s", expected, got) + } +} diff --git a/06_puppy/patrickmarabeas/mapStore.go b/06_puppy/patrickmarabeas/mapStore.go new file mode 100644 index 000000000..f23af91ef --- /dev/null +++ b/06_puppy/patrickmarabeas/mapStore.go @@ -0,0 +1,56 @@ +package main + +type MapStore struct { + uuid uint + store map[uint]Puppy +} + +// NewMapStore returns a pointer to a new instance of the MapStore struct which implements the Storer interface. +func NewMapStore() Storer { + return &MapStore{ + uuid: 0, + store: map[uint]Puppy{}, + } +} + +// Create increments the uuid and adds the provided Puppy struct to the store with this identifier. +func (store *MapStore) Create(puppy Puppy) uint { + puppy.ID = store.uuid + store.store[puppy.ID] = puppy + store.uuid++ + + return puppy.ID +} + +// Read returns the puppy matching the provided uuid. +// An empty Puppy struct is returned if the identifier does not exist. +func (store *MapStore) Read(id uint) Puppy { + if _, ok := store.store[id]; ok { + return store.store[id] + } + + return Puppy{} +} + +// Update modifies the puppy matching the provided uuid in the store with the provided Puppy struct. +// It returns a bool whether a matching identifier was modified or not. +func (store *MapStore) Update(id uint, puppy Puppy) bool { + if _, ok := store.store[id]; !ok { + return false + } + + puppy.ID = id + store.store[id] = puppy + return true +} + +// Destroy removes the puppy matching the provided uuid from the store. +// It returns a bool whether a matching identifier was deleted or not. +func (store *MapStore) Destroy(id uint) bool { + if _, ok := store.store[id]; !ok { + return false + } + + delete(store.store, id) + return true +} diff --git a/06_puppy/patrickmarabeas/store_test.go b/06_puppy/patrickmarabeas/store_test.go new file mode 100644 index 000000000..4c93c3639 --- /dev/null +++ b/06_puppy/patrickmarabeas/store_test.go @@ -0,0 +1,81 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +type StoreSuite struct { + suite.Suite + store Storer +} + +func (suite *StoreSuite) TestCreate() { + a := assert.New(suite.T()) + id := suite.store.Create(Puppy{Breed: "Wolf", Color: "Grey", Value: "450"}) + id2 := suite.store.Create(Puppy{Breed: "Boxer", Color: "Brown", Value: "300"}) + + a.EqualValues(id+1, id2) +} + +func (suite *StoreSuite) TestRead() { + a := assert.New(suite.T()) + data := suite.store.Read(0) + + a.Equal(data, Puppy{ID: 0, Breed: "Wolf", Color: "Grey", Value: "450"}) +} + +func (suite *StoreSuite) TestReadNonExistent() { + a := assert.New(suite.T()) + success := suite.store.Read(100) + + a.Equal(success, Puppy{}) +} + +func (suite *StoreSuite) TestUpdate() { + a := assert.New(suite.T()) + success := suite.store.Update(0, Puppy{Breed: "Doberman", Color: "Black", Value: "500"}) + data := suite.store.Read(0) + + a.Equal(success, true) + a.Equal(data, Puppy{ID: 0, Breed: "Doberman", Color: "Black", Value: "500"}) +} + +func (suite *StoreSuite) TestUpdateNonExistent() { + a := assert.New(suite.T()) + success := suite.store.Update(100, Puppy{Breed: "Doberman", Color: "Black", Value: "500"}) + + a.Equal(success, false) +} + +func (suite *StoreSuite) TestDestroy() { + a := assert.New(suite.T()) + success := suite.store.Destroy(1) + data := suite.store.Read(1) + + a.Equal(success, true) + a.Equal(data, Puppy{}) +} + +func (suite *StoreSuite) TestDestroyNonExistent() { + a := assert.New(suite.T()) + success := suite.store.Destroy(100) + + a.Equal(success, false) +} + +func (suite *StoreSuite) TestIdIncrementOnDelete() { + a := assert.New(suite.T()) + id := suite.store.Create(Puppy{Breed: "Greyhound", Color: "Light Brown", Value: "700"}) + suite.store.Destroy(id) + newID := suite.store.Create(Puppy{Breed: "Greyhound", Color: "Light Brown", Value: "700"}) + + a.EqualValues(newID, 3) +} + +func TestStore(t *testing.T) { + suite.Run(t, &StoreSuite{store: NewMapStore()}) + suite.Run(t, &StoreSuite{store: NewSyncStore()}) +} diff --git a/06_puppy/patrickmarabeas/syncStore.go b/06_puppy/patrickmarabeas/syncStore.go new file mode 100644 index 000000000..74911a005 --- /dev/null +++ b/06_puppy/patrickmarabeas/syncStore.go @@ -0,0 +1,59 @@ +package main + +import ( + "sync" +) + +type SyncStore struct { + uuid uint + sync.Map +} + +// NewSyncStore returns a pointer to a new instance of the SyncStore struct which implements the Storer interface. +func NewSyncStore() Storer { + return &SyncStore{ + uuid: 0, + } +} + +// Create increments the uuid and adds the provided Puppy struct to the store with this identifier. +func (store *SyncStore) Create(puppy Puppy) uint { + puppy.ID = store.uuid + store.Store(puppy.ID, puppy) + store.uuid++ + + return puppy.ID +} + +// Read returns the puppy matching the provided uuid. +// An empty Puppy struct is returned if the identifier does not exist. +func (store *SyncStore) Read(id uint) Puppy { + if value, ok := store.Load(id); ok { + return value.(Puppy) + } + + return Puppy{} +} + +// Update modifies the puppy matching the provided uuid in the store with the provided Puppy struct. +// It returns a bool whether a matching identifier was modified or not. +func (store *SyncStore) Update(id uint, puppy Puppy) bool { + if _, ok := store.Load(id); !ok { + return false + } + + puppy.ID = id + store.Store(id, puppy) + return true +} + +// Destroy removes the puppy matching the provided uuid from the store. +// It returns a bool whether a matching identifier was deleted or not. +func (store *SyncStore) Destroy(id uint) bool { + if _, ok := store.Load(id); !ok { + return false + } + + store.Delete(id) + return true +} diff --git a/06_puppy/patrickmarabeas/types.go b/06_puppy/patrickmarabeas/types.go new file mode 100644 index 000000000..3f47c86ca --- /dev/null +++ b/06_puppy/patrickmarabeas/types.go @@ -0,0 +1,15 @@ +package main + +type Puppy struct { + ID uint + Breed string + Color string + Value string +} + +type Storer interface { + Create(puppy Puppy) uint + Read(ID uint) Puppy + Update(ID uint, puppy Puppy) bool + Destroy(ID uint) bool +}