Skip to content

Commit 3181c18

Browse files
committed
Added demo code
0 parents  commit 3181c18

File tree

12 files changed

+576
-0
lines changed

12 files changed

+576
-0
lines changed

demo_01/main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package main
2+
3+
import "fmt"
4+
5+
func main() {
6+
fmt.Printf("Sum of %v and %v is %v", 2, 4, AddTwoNumbers(2, 4))
7+
}
8+
9+
func AddTwoNumbers(a, b int) int {
10+
return a + b
11+
}

demo_01/main_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func TestAdd(t *testing.T) {
9+
expected := 6
10+
actual := AddTwoNumbers(2, 4)
11+
12+
if actual != expected {
13+
t.Fatal(fmt.Sprintf("expected %v, got %v", expected, actual))
14+
}
15+
}

demo_02/bank.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
)
7+
8+
type TransactionManger interface {
9+
TransactionReader
10+
TransactionWriter
11+
}
12+
13+
type TransactionReader interface {
14+
ReadBalance(int) (int, error)
15+
}
16+
17+
type TransactionWriter interface {
18+
UpdateBalance(int, int) error
19+
}
20+
21+
type SqlTransactionManager struct{}
22+
23+
func (stm SqlTransactionManager) ReadBalance(amount int) (int, error) {
24+
fmt.Print("Represents reading a real db")
25+
return 10, nil
26+
}
27+
28+
func (stm SqlTransactionManager) UpdateBalance(amount, account int) error {
29+
fmt.Print("represents updating real db")
30+
return nil
31+
}
32+
33+
type Account interface {
34+
Balance(TransactionReader) (int, error)
35+
Withdraw(int, TransactionManger) error
36+
Deposit(int, TransactionManger) error
37+
}
38+
39+
type ChequingAccount struct {
40+
AccountNumber int
41+
}
42+
43+
func (ca ChequingAccount) Balance(tr TransactionReader) (int, error) {
44+
// just for tests
45+
if ca.AccountNumber == 22 {
46+
return 0, fmt.Errorf("account %v is invalid", ca.AccountNumber)
47+
}
48+
balance, err := tr.ReadBalance(ca.AccountNumber)
49+
if err != nil {
50+
return 0, fmt.Errorf("error occured reading balance, %v", err)
51+
}
52+
return balance, nil
53+
}
54+
55+
func (ca ChequingAccount) Deposit(amount int, tm TransactionManger) error {
56+
balance, err := ca.Balance(tm)
57+
if err != nil {
58+
return errors.New("failed to get balance for update")
59+
}
60+
err = tm.UpdateBalance(ca.AccountNumber, balance+amount)
61+
if err != nil {
62+
return errors.New("error occured updating balance")
63+
}
64+
fmt.Printf("Deposited %v", amount)
65+
return nil
66+
}
67+
68+
func (ca ChequingAccount) Withdraw(amount int, tm TransactionManger) error {
69+
balance, err := ca.Balance(tm)
70+
if err != nil {
71+
return errors.New("failed to get balance for update")
72+
}
73+
if amount > balance {
74+
return errors.New("amount greated than balance")
75+
}
76+
tm.UpdateBalance(ca.AccountNumber, balance-amount)
77+
err = tm.UpdateBalance(ca.AccountNumber, balance+amount)
78+
if err != nil {
79+
return errors.New("error occured updating balance")
80+
}
81+
fmt.Printf("Withdrawn %v", amount)
82+
return nil
83+
}

demo_02/bank_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"testing"
7+
)
8+
9+
var ErrNotImplemented = errors.New("not implemented")
10+
11+
type TransactionMangerStub struct {
12+
HandleReadBalance func(int) (int, error)
13+
HandleUpdateBalance func(int, int) error
14+
}
15+
16+
func (tms TransactionMangerStub) ReadBalance(account int) (int, error) {
17+
if tms.HandleReadBalance == nil {
18+
return 0, ErrNotImplemented
19+
}
20+
21+
return tms.HandleReadBalance(account)
22+
}
23+
24+
func (tms TransactionMangerStub) UpdateBalance(amount, account int) error {
25+
if tms.HandleUpdateBalance == nil {
26+
return ErrNotImplemented
27+
}
28+
29+
return tms.HandleUpdateBalance(amount, account)
30+
}
31+
32+
func TestReadBalanceEdgeCases(t *testing.T) {
33+
tt := map[string]struct {
34+
accountNumber int
35+
transactionReaderBehavior func(int) (int, error)
36+
}{
37+
"AccountNumberInvalid": {
38+
accountNumber: 22,
39+
transactionReaderBehavior: successfulRead100},
40+
"FailedRead": {
41+
accountNumber: 1,
42+
transactionReaderBehavior: func(int) (int, error) { return 0, errors.New("failed to read balance") }},
43+
}
44+
45+
for name, test := range tt {
46+
t.Run(name, func(t *testing.T) {
47+
tm := TransactionMangerStub{HandleReadBalance: test.transactionReaderBehavior}
48+
account := ChequingAccount{AccountNumber: test.accountNumber}
49+
50+
_, err := account.Balance(tm)
51+
52+
if err == nil {
53+
t.Fatal("Failure expected, but got no error")
54+
}
55+
})
56+
}
57+
}
58+
59+
func TestReadBalance(t *testing.T) {
60+
tm := TransactionMangerStub{HandleReadBalance: successfulRead100}
61+
62+
account := ChequingAccount{AccountNumber: 1}
63+
balance, err := account.Balance(tm)
64+
if err != nil {
65+
t.Fatal("error not expected when reading balance")
66+
}
67+
68+
if balance != 100 {
69+
t.Fatal(fmt.Sprintf("expected balance 100, got %v", balance))
70+
}
71+
}
72+
73+
func TestDeposit(t *testing.T) {
74+
tm := TransactionMangerStub{HandleReadBalance: successfulRead100, HandleUpdateBalance: func(int, int) error { return nil }}
75+
76+
account := ChequingAccount{AccountNumber: 1}
77+
err := account.Deposit(100, tm)
78+
79+
if err != nil {
80+
t.Fatal(fmt.Sprintf("expected no error on deposit, got %v", err))
81+
}
82+
}
83+
84+
func successfulRead100(int) (int, error) {
85+
return 100, nil
86+
}

demo_02/main.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
func main() {
8+
fmt.Print("hello world!")
9+
10+
tm := SqlTransactionManager{}
11+
12+
acc := ChequingAccount{AccountNumber: 1}
13+
acc.Deposit(100, tm)
14+
}

demo_03/bank.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"fmt"
7+
"net/http"
8+
)
9+
10+
type TransactionManger interface {
11+
TransactionReader
12+
TransactionWriter
13+
}
14+
15+
type TransactionReader interface {
16+
ReadBalance(int) (int, error)
17+
}
18+
19+
type TransactionWriter interface {
20+
UpdateBalance(int, int) error
21+
}
22+
23+
type SqlTransactionManager struct{}
24+
25+
func (stm SqlTransactionManager) ReadBalance(amount int) (int, error) {
26+
fmt.Print("Represents reading a real db")
27+
return 10, nil
28+
}
29+
30+
func (stm SqlTransactionManager) UpdateBalance(amount, account int) error {
31+
fmt.Print("represents updating real db")
32+
return nil
33+
}
34+
35+
type Account interface {
36+
Balance(TransactionReader) (int, error)
37+
BalanceCAD(TransactionReader) (int, error)
38+
Withdraw(int, TransactionManger) error
39+
Deposit(int, TransactionManger) error
40+
}
41+
42+
type ChequingAccount struct {
43+
AccountNumber int
44+
}
45+
46+
func (ca ChequingAccount) Balance(tr TransactionReader) (int, error) {
47+
// just for tests
48+
if ca.AccountNumber == 22 {
49+
return 0, fmt.Errorf("account %v is invalid", ca.AccountNumber)
50+
}
51+
balance, err := tr.ReadBalance(ca.AccountNumber)
52+
if err != nil {
53+
return 0, fmt.Errorf("error occured reading balance, %v", err)
54+
}
55+
return balance, nil
56+
}
57+
58+
func (ca ChequingAccount) BalanceCAD(url string, tr TransactionReader) (int, error) {
59+
balance, _ := ca.Balance(tr)
60+
if url == "" {
61+
url = "https://api.exchangerate-api.com/v4/latest/usd"
62+
}
63+
res, err := http.Get(url)
64+
if err != nil {
65+
return 0, err
66+
}
67+
response := Response{}
68+
69+
json.NewDecoder(res.Body).Decode(&response)
70+
71+
return int(response.Rates.CAD * float64(balance)), nil
72+
}
73+
74+
func (ca ChequingAccount) Deposit(amount int, tm TransactionManger) error {
75+
balance, err := ca.Balance(tm)
76+
if err != nil {
77+
return errors.New("failed to get balance for update")
78+
}
79+
err = tm.UpdateBalance(ca.AccountNumber, balance+amount)
80+
if err != nil {
81+
return errors.New("error occured updating balance")
82+
}
83+
fmt.Printf("Deposited %v", amount)
84+
return nil
85+
}
86+
87+
func (ca ChequingAccount) Withdraw(amount int, tm TransactionManger) error {
88+
balance, err := ca.Balance(tm)
89+
if err != nil {
90+
return errors.New("failed to get balance for update")
91+
}
92+
if amount > balance {
93+
return errors.New("amount greated than balance")
94+
}
95+
tm.UpdateBalance(ca.AccountNumber, balance-amount)
96+
err = tm.UpdateBalance(ca.AccountNumber, balance+amount)
97+
if err != nil {
98+
return errors.New("error occured updating balance")
99+
}
100+
fmt.Printf("Withdrawn %v", amount)
101+
return nil
102+
}
103+
104+
type Response struct {
105+
Rates struct {
106+
CAD float64 `json:"CAD"`
107+
}
108+
}

demo_03/bank_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"testing"
6+
)
7+
8+
var ErrNotImplemented = errors.New("not implemented")
9+
10+
type TransactionReaderStub struct {
11+
HandleReadBalance func(int) (int, error)
12+
}
13+
14+
func (tms TransactionReaderStub) ReadBalance(account int) (int, error) {
15+
if tms.HandleReadBalance == nil {
16+
return 0, ErrNotImplemented
17+
}
18+
19+
return tms.HandleReadBalance(account)
20+
}
21+
22+
func TestBalanceEndpoint(t *testing.T) {
23+
24+
}
25+
26+
func TestBalanceEndpointWithTestServer(t *testing.T) {
27+
28+
}

demo_03/main.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net/http"
7+
"strconv"
8+
)
9+
10+
var transactionReader TransactionReader = SqlTransactionManager{}
11+
12+
func main() {
13+
err := http.ListenAndServe(":8080", handler())
14+
if err != nil {
15+
log.Fatal(err)
16+
}
17+
}
18+
19+
func handler() http.Handler {
20+
r := http.NewServeMux()
21+
r.HandleFunc("/balance", balanceHandler)
22+
return r
23+
}
24+
25+
func balanceHandler(w http.ResponseWriter, r *http.Request) {
26+
account := r.URL.Query().Get("account")
27+
if account == "" {
28+
http.Error(w, "missing value", http.StatusBadRequest)
29+
return
30+
}
31+
accountNumeric, err := strconv.Atoi(account)
32+
if err != nil {
33+
http.Error(w, "unable to parse account value", http.StatusBadRequest)
34+
}
35+
36+
acc := ChequingAccount{AccountNumber: accountNumeric}
37+
balance, err := acc.Balance(transactionReader)
38+
if err != nil {
39+
http.Error(w, "an error occured serving your request", http.StatusInternalServerError)
40+
}
41+
42+
fmt.Fprintln(w, balance)
43+
}

0 commit comments

Comments
 (0)