Skip to content

Commit 51affc7

Browse files
authored
expand on maps delete to handle the case where word doesn't exist (quii#787)
1 parent 6d7369e commit 51affc7

File tree

4 files changed

+96
-14
lines changed

4 files changed

+96
-14
lines changed

maps.md

+60-3
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ We get 3 errors this time, but we know how to deal with these.
537537
const (
538538
ErrNotFound = DictionaryErr("could not find the word you were looking for")
539539
ErrWordExists = DictionaryErr("cannot add word because it already exists")
540-
ErrWordDoesNotExist = DictionaryErr("cannot update word because it does not exist")
540+
ErrWordDoesNotExist = DictionaryErr("cannot perform operation on word because it does not exist")
541541
)
542542

543543
func (d Dictionary) Update(word, definition string) error {
@@ -631,9 +631,66 @@ func (d Dictionary) Delete(word string) {
631631
}
632632
```
633633

634-
Go has a built-in function `delete` that works on maps. It takes two arguments. The first is the map and the second is the key to be removed.
634+
Go has a built-in function `delete` that works on maps. It takes two arguments and returns nothing. The first argument is the map and the second is the key to be removed.
635635

636-
The `delete` function returns nothing, and we based our `Delete` method on the same notion. Since deleting a value that's not there has no effect, unlike our `Update` and `Add` methods, we don't need to complicate the API with errors.
636+
## Refactor
637+
There isn't much to refactor, but we can implement the same logic from `Update` to handle cases where word doesn't exist.
638+
639+
```go
640+
func TestDelete(t *testing.T) {
641+
t.Run("existing word", func(t *testing.T) {
642+
word := "test"
643+
dictionary := Dictionary{word: "test definition"}
644+
645+
err := dictionary.Delete(word)
646+
647+
assertError(t, err, nil)
648+
649+
_, err = dictionary.Search(word)
650+
651+
assertError(t, err, ErrNotFound)
652+
})
653+
654+
t.Run("non-existing word", func(t *testing.T) {
655+
word := "test"
656+
dictionary := Dictionary{}
657+
658+
err := dictionary.Delete(word)
659+
660+
assertError(t, err, ErrWordDoesNotExist)
661+
})
662+
}
663+
```
664+
665+
## Try to run test
666+
667+
The compiler will fail because we are not returning a value for `Delete`.
668+
669+
```
670+
./dictionary_test.go:77:10: dictionary.Delete(word) (no value) used as value
671+
./dictionary_test.go:90:10: dictionary.Delete(word) (no value) used as value
672+
```
673+
674+
## Write enough code to make it pass
675+
676+
```go
677+
func (d Dictionary) Delete(word string) error {
678+
_, err := d.Search(word)
679+
680+
switch err {
681+
case ErrNotFound:
682+
return ErrWordDoesNotExist
683+
case nil:
684+
delete(d, word)
685+
default:
686+
return err
687+
}
688+
689+
return nil
690+
}
691+
```
692+
693+
We are again using a switch statement to match on the error when we attempt to delete a word that doesn't exist.
637694

638695
## Wrapping up
639696

maps/v6/dictionary.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ const (
77
// ErrWordExists means you are trying to add a word that is already known
88
ErrWordExists = DictionaryErr("cannot add word because it already exists")
99

10-
// ErrWordDoesNotExist occurs when trying to update a word not in the dictionary
11-
ErrWordDoesNotExist = DictionaryErr("cannot update word because it does not exist")
10+
// ErrWordDoesNotExist occurs when trying to perform an operation on a word not in the dictionary
11+
ErrWordDoesNotExist = DictionaryErr("cannot perform operation on word because it does not exist")
1212
)
1313

1414
// DictionaryErr are errors that can happen when interacting with the dictionary.

maps/v7/dictionary.go

+15-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ const (
77
// ErrWordExists means you are trying to add a word that is already known
88
ErrWordExists = DictionaryErr("cannot add word because it already exists")
99

10-
// ErrWordDoesNotExist occurs when trying to update a word not in the dictionary
11-
ErrWordDoesNotExist = DictionaryErr("cannot update word because it does not exist")
10+
// ErrWordDoesNotExist occurs when trying to perform an operation on a word not in the dictionary
11+
ErrWordDoesNotExist = DictionaryErr("cannot perform operation on word because it does not exist")
1212
)
1313

1414
// DictionaryErr are errors that can happen when interacting with the dictionary.
@@ -64,6 +64,17 @@ func (d Dictionary) Update(word, definition string) error {
6464
}
6565

6666
// Delete removes a word from the dictionary.
67-
func (d Dictionary) Delete(word string) {
68-
delete(d, word)
67+
func (d Dictionary) Delete(word string) error {
68+
_, err := d.Search(word)
69+
switch err {
70+
case ErrNotFound:
71+
return ErrWordDoesNotExist
72+
case nil:
73+
delete(d, word)
74+
default:
75+
return err
76+
77+
}
78+
79+
return nil
6980
}

maps/v7/dictionary_test.go

+19-5
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,27 @@ func TestUpdate(t *testing.T) {
6868
}
6969

7070
func TestDelete(t *testing.T) {
71-
word := "test"
72-
dictionary := Dictionary{word: "test definition"}
71+
t.Run("existing word", func(t *testing.T) {
72+
word := "test"
73+
dictionary := Dictionary{word: "test definition"}
7374

74-
dictionary.Delete(word)
75+
err := dictionary.Delete(word)
76+
77+
assertError(t, err, nil)
78+
79+
_, err = dictionary.Search(word)
80+
81+
assertError(t, err, ErrNotFound)
82+
})
7583

76-
_, err := dictionary.Search(word)
77-
assertError(t, err, ErrNotFound)
84+
t.Run("non-existing word", func(t *testing.T) {
85+
word := "test"
86+
dictionary := Dictionary{}
87+
88+
err := dictionary.Delete(word)
89+
90+
assertError(t, err, ErrWordDoesNotExist)
91+
})
7892
}
7993

8094
func assertStrings(t testing.TB, got, want string) {

0 commit comments

Comments
 (0)