-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement custom error handling to Storer interface #590
Changes from 1 commit
1358c73
bb43faf
c52f22a
5fa4311
8efff56
e6dbc8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,43 +9,50 @@ func NewMapStore() Storer { | |
} | ||
|
||
// Create increments the uuid and adds the provided Puppy struct to the store with this identifier. | ||
func (store *MapStore) Create(puppy Puppy) int { | ||
func (store *MapStore) Create(puppy Puppy) (int, error) { | ||
if puppy.Value < 0 { | ||
return -1, NewError(NegativeValue) | ||
} | ||
|
||
puppy.ID = store.uuid | ||
store.store[puppy.ID] = puppy | ||
store.uuid++ | ||
|
||
return puppy.ID | ||
return puppy.ID, nil | ||
} | ||
|
||
// 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 int) Puppy { | ||
func (store *MapStore) Read(id int) (Puppy, error) { | ||
if _, ok := store.store[id]; ok { | ||
return store.store[id] | ||
return store.store[id], nil | ||
} | ||
|
||
return Puppy{} | ||
return Puppy{}, NewError(IDNotFound) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two comments about this function (and I know my comments really apply to lab 6, not this one but here we are now):
unless you use a
|
||
} | ||
|
||
// 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 int, puppy Puppy) bool { | ||
func (store *MapStore) Update(id int, puppy Puppy) (bool, error) { | ||
if _, ok := store.store[id]; !ok { | ||
return false | ||
return false, NewError(IDNotFound) | ||
} | ||
if puppy.Value < 0 { | ||
return false, NewError(NegativeValue) | ||
} | ||
|
||
puppy.ID = id | ||
store.store[id] = puppy | ||
return true | ||
return true, nil | ||
} | ||
|
||
// 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 int) bool { | ||
func (store *MapStore) Destroy(id int) (bool, error) { | ||
if _, ok := store.store[id]; !ok { | ||
return false | ||
return false, NewError(IDNotFound) | ||
} | ||
|
||
delete(store.store, id) | ||
return true | ||
return true, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,70 +14,99 @@ type StoreSuite struct { | |
|
||
func (suite *StoreSuite) TestCreate() { | ||
a := assert.New(suite.T()) | ||
id := suite.store.Create(Puppy{Breed: "Wolf", Color: "Grey", Value: "450"}) | ||
|
||
id, error := suite.store.Create(Puppy{Breed: "Wolf", Color: "Grey", Value: 450}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be called |
||
a.Equal(id, 0) | ||
a.Equal(error, nil) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
} | ||
|
||
func (suite *StoreSuite) TestCreateSecond() { | ||
a := assert.New(suite.T()) | ||
id := suite.store.Create(Puppy{Breed: "Boxer", Color: "Brown", Value: "300"}) | ||
|
||
id, error := suite.store.Create(Puppy{Breed: "Boxer", Color: "Brown", Value: 300}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/error/err/ |
||
a.Equal(id, 1) | ||
a.Equal(error, nil) | ||
} | ||
|
||
func (suite *StoreSuite) TestCreateNegativeNumber() { | ||
a := assert.New(suite.T()) | ||
|
||
id, error := suite.store.Create(Puppy{Breed: "Wolf", Color: "Grey", Value: -100}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/error/err/ |
||
a.Equal(id, -1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
a.Equal(error, NewError(NegativeValue)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
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"}) | ||
data, error := suite.store.Read(0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/error/err/ Going to stop saying this now. Please fix throughout |
||
a.Equal(data, Puppy{ID: 0, Breed: "Wolf", Color: "Grey", Value: 450}) | ||
a.Equal(error, nil) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Going to stop saying this now. Please fix throughout. |
||
} | ||
|
||
func (suite *StoreSuite) TestReadNonExistent() { | ||
a := assert.New(suite.T()) | ||
success := suite.store.Read(100) | ||
|
||
success, error := suite.store.Read(100) | ||
a.Equal(success, Puppy{}) | ||
a.Equal(error, NewError(IDNotFound)) | ||
} | ||
|
||
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) | ||
|
||
success, error := suite.store.Update(0, Puppy{Breed: "Doberman", Color: "Black", Value: 500}) | ||
a.Equal(success, true) | ||
a.Equal(data, Puppy{ID: 0, Breed: "Doberman", Color: "Black", Value: "500"}) | ||
a.Equal(error, nil) | ||
|
||
data, error := suite.store.Read(0) | ||
a.Equal(data, Puppy{ID: 0, Breed: "Doberman", Color: "Black", Value: 500}) | ||
a.Equal(error, nil) | ||
} | ||
|
||
func (suite *StoreSuite) TestUpdateNonExistent() { | ||
a := assert.New(suite.T()) | ||
success := suite.store.Update(100, Puppy{Breed: "Doberman", Color: "Black", Value: "500"}) | ||
|
||
success, error := suite.store.Update(100, Puppy{Breed: "Doberman", Color: "Black", Value: 500}) | ||
a.Equal(success, false) | ||
a.Equal(error, NewError(IDNotFound)) | ||
} | ||
|
||
func (suite *StoreSuite) TestUpdateNegativeNumber() { | ||
a := assert.New(suite.T()) | ||
|
||
success, error := suite.store.Update(0, Puppy{Breed: "Doberman", Color: "Black", Value: -500}) | ||
a.Equal(success, false) | ||
a.Equal(error, NewError(NegativeValue)) | ||
} | ||
|
||
func (suite *StoreSuite) TestDestroy() { | ||
a := assert.New(suite.T()) | ||
success := suite.store.Destroy(1) | ||
data := suite.store.Read(1) | ||
|
||
success, error := suite.store.Destroy(1) | ||
a.Equal(success, true) | ||
a.Equal(error, nil) | ||
|
||
data, error := suite.store.Read(1) | ||
a.Equal(data, Puppy{}) | ||
a.Equal(error, NewError(IDNotFound)) | ||
} | ||
|
||
func (suite *StoreSuite) TestDestroyNonExistent() { | ||
a := assert.New(suite.T()) | ||
success := suite.store.Destroy(100) | ||
|
||
success, error := suite.store.Destroy(100) | ||
a.Equal(success, false) | ||
a.Equal(error, NewError(IDNotFound)) | ||
} | ||
|
||
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"}) | ||
id, _ := suite.store.Create(Puppy{Breed: "Greyhound", Color: "Light Brown", Value: 700}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than ignoring the error here, perhaps use
|
||
success, _ := suite.store.Destroy(id) | ||
a.Equal(success, true) | ||
|
||
newID, _ := suite.store.Create(Puppy{Breed: "Greyhound", Color: "Light Brown", Value: 700}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar. You do not expect this |
||
a.Equal(newID, 3) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,43 +8,50 @@ func NewSyncStore() Storer { | |
} | ||
|
||
// Create increments the uuid and adds the provided Puppy struct to the store with this identifier. | ||
func (store *SyncStore) Create(puppy Puppy) int { | ||
func (store *SyncStore) Create(puppy Puppy) (int, error) { | ||
if puppy.Value < 0 { | ||
return -1, NewError(NegativeValue) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similar to mapstore - use a zero value for unspecified return values. |
||
} | ||
|
||
puppy.ID = store.uuid | ||
store.Store(puppy.ID, puppy) | ||
store.uuid++ | ||
|
||
return puppy.ID | ||
return puppy.ID, nil | ||
} | ||
|
||
// 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 int) Puppy { | ||
func (store *SyncStore) Read(id int) (Puppy, error) { | ||
if value, ok := store.Load(id); ok { | ||
return value.(Puppy) | ||
return value.(Puppy), nil | ||
} | ||
|
||
return Puppy{} | ||
return Puppy{}, NewError(IDNotFound) | ||
} | ||
|
||
// 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 int, puppy Puppy) bool { | ||
func (store *SyncStore) Update(id int, puppy Puppy) (bool, error) { | ||
if _, ok := store.Load(id); !ok { | ||
return false | ||
return false, NewError(IDNotFound) | ||
} | ||
if puppy.Value < 0 { | ||
return false, NewError(NegativeValue) | ||
} | ||
|
||
puppy.ID = id | ||
store.Store(id, puppy) | ||
return true | ||
return true, nil | ||
} | ||
|
||
// 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 int) bool { | ||
func (store *SyncStore) Destroy(id int) (bool, error) { | ||
if _, ok := store.Load(id); !ok { | ||
return false | ||
return false, NewError(IDNotFound) | ||
} | ||
|
||
store.Delete(id) | ||
return true | ||
return true, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be
return 0, NewError(NegativeValue)
When an error is returned, the value of the other return parameters should be the zero value for their type. Otherwise people may start checking the wrong value for errors, or try to use those values thinking there might be some significance to the non-zero-value.