diff --git a/pointers/wallet.go b/pointers/wallet.go new file mode 100644 index 0000000..df36654 --- /dev/null +++ b/pointers/wallet.go @@ -0,0 +1,35 @@ +package pointers + +import ( + "errors" + "fmt" +) + +type Bitcoin int + +type Wallet struct { + balance Bitcoin +} + +func (w *Wallet) Deposit(a Bitcoin) { + w.balance += a +} + +var ErrInsufficientFunds = errors.New("cannot withdraw, insufficient funds") + +func (w *Wallet) Withdraw(a Bitcoin) error { + if a > w.balance { + return ErrInsufficientFunds + } + + w.balance -= a + return nil +} + +func (w Wallet) Balance() Bitcoin { + return w.balance +} + +func (b Bitcoin) String() string { + return fmt.Sprintf("%d BTC", b) +} diff --git a/pointers/wallet_test.go b/pointers/wallet_test.go new file mode 100644 index 0000000..8608fd6 --- /dev/null +++ b/pointers/wallet_test.go @@ -0,0 +1,52 @@ +package pointers + +import ( + "testing" +) + +func TestWallet(t *testing.T) { + assertBalance := func(t testing.TB, w Wallet, want Bitcoin) { + t.Helper() + balance := w.Balance() + + if balance != want { + t.Errorf("got %s want %s", balance, want) + } + } + + t.Run("Deposit", func(t *testing.T) { + wallet := Wallet{} + wallet.Deposit(Bitcoin(10)) + want := Bitcoin(10) + + assertBalance(t, wallet, want) + }) + + t.Run("Withdraw", func(t *testing.T) { + wallet := Wallet{balance: Bitcoin(20)} + wallet.Withdraw(Bitcoin(10)) + + want := Bitcoin(10) + assertBalance(t, wallet, want) + }) + + assertError := func(t testing.TB, got, want error) { + t.Helper() + + if got == nil { + t.Fatal("wanted an error but didn't get one") + } + + if got != want { + t.Errorf("got %q, want %q", got, want) + } + } + + t.Run("Withdraw insufficient funds", func(t *testing.T) { + startingBalance := Bitcoin(20) + wallet := Wallet{startingBalance} + err := wallet.Withdraw(Bitcoin(100)) + assertError(t, err, ErrInsufficientFunds) + assertBalance(t, wallet, startingBalance) + }) +}