Skip to content

Instantly share code, notes, and snippets.

@martinusso
Created February 4, 2022 20:23
Show Gist options
  • Save martinusso/5c73a392902e1a7ea8516896367016c6 to your computer and use it in GitHub Desktop.
Save martinusso/5c73a392902e1a7ea8516896367016c6 to your computer and use it in GitHub Desktop.
loft dojo - bank account
module test-dojo
go 1.16
package main
import "sync"
type Account struct {
Amount int64
Closed bool
mtx *sync.Mutex
}
func Desafio(input string) (bool, error) {
return true, nil
}
// Define the Account type here.
func Open(amount int64) *Account {
if amount < 0 {
return nil
}
acc := Account{
Amount: amount,
Closed: false,
mtx: &sync.Mutex{},
}
return &acc
}
func OpenClosedAccount(amount int64) *Account {
if amount < 0 {
return nil
}
acc := Account{
Amount: amount,
Closed: true,
mtx: &sync.Mutex{},
}
return &acc
}
func (a *Account) Balance() (int64, bool) {
return a.Amount, a.Closed
}
func (a *Account) Deposit(amount int64) (int64, bool) {
a.mtx.Lock()
defer a.mtx.Unlock()
saldo, closed := a.Balance()
saldo += amount
if saldo < 0 || closed {
return a.Amount, false
}
a.Amount = saldo
return saldo, true
}
func (a *Account) Close() (int64, bool) {
a.Closed = true
return a.Balance()
}
package main
import (
"reflect"
"sync"
"testing"
)
func TestOpen(t *testing.T) {
type test struct {
name string
input int64
want *Account
err error
}
tests := []test{
{name: "Abrir conta positivo", input: 10, want: &Account{
Amount: 10,
Closed: false,
mtx: &sync.Mutex{},
}},
{name: "Abrir conta negativo", input: -10, want: nil},
}
for _, tc := range tests {
got := Open(tc.input)
if !reflect.DeepEqual(tc.want, got) {
t.Fatalf("%s expected: %v, got: %v", tc.name, tc.want, got)
}
}
}
func TestDeposit(t *testing.T) {
type test struct {
name string
account *Account
input int64
want1 int64
want2 bool
}
tests := []test{
{name: "Depositar valor positivo", account: Open(20),
input: 10, want1: 30, want2: true},
{name: "Depositar valor negativo indevido", account: Open(20),
input: -30, want1: 20, want2: false},
{name: "Depositar valor negativo devido", account: Open(20),
input: -10, want1: 10, want2: true},
{name: "Depositar valor com conta fechada", account: OpenClosedAccount(20),
input: -10, want1: 20, want2: false},
}
for _, tc := range tests {
got, got2 := tc.account.Deposit(tc.input)
if !reflect.DeepEqual(tc.want1, got) {
t.Fatalf("%s expected: %v, got: %v", tc.name, tc.want1, got)
}
if !reflect.DeepEqual(tc.want2, got2) {
t.Fatalf("%s expected: %v, got: %v", tc.name, tc.want2, got2)
}
}
}
func TestDepositWithConcurrency(t *testing.T) {
type test struct {
name string
account *Account
input []int64
want1 int64
want2 bool
}
tests := []test{
{
name: "Depositar valor positivo",
account: Open(20),
input: []int64{10, 10, 50, 30, -10, -10, -10, -10, -10},
want1: 70,
want2: true,
},
}
for _, tc := range tests {
var wg sync.WaitGroup
for _, i := range tc.input {
wg.Add(1)
go func(i int64) {
tc.account.Deposit(i)
wg.Done()
}(i)
}
wg.Wait()
balance, _ := tc.account.Balance()
if !reflect.DeepEqual(tc.want1, balance) {
t.Fatalf("%s expected: %v, got: %v", tc.name, tc.want1, balance)
}
}
}
func TestBalance(t *testing.T) {
type test struct {
name string
account Account
want1 int64
want2 bool
}
tests := []test{
{name: "Buscar conta aberta", account: Account{
Amount: 20,
Closed: false,
mtx: &sync.Mutex{},
},
want1: 20, want2: false},
{name: "Buscar conta fechada", account: Account{
Amount: 30,
Closed: true,
mtx: &sync.Mutex{},
}, want1: 30, want2: true},
}
for _, tc := range tests {
got, got2 := tc.account.Balance()
if !reflect.DeepEqual(tc.want1, got) {
t.Fatalf("%s expected: %v, got: %v", tc.name, tc.want1, got)
}
if !reflect.DeepEqual(tc.want2, got2) {
t.Fatalf("%s expected: %v, got: %v", tc.name, tc.want2, got2)
}
}
}
func TestClose(t *testing.T) {
type test struct {
name string
account Account
want1 int64
want2 bool
}
tests := []test{
{name: "Fechar conta aberta", account: Account{
Amount: 20,
Closed: false,
mtx: &sync.Mutex{},
},
want1: 20, want2: true},
{name: "Ferchar conta fechada", account: Account{
Amount: 30,
Closed: true,
mtx: &sync.Mutex{},
}, want1: 30, want2: true},
}
for _, tc := range tests {
got, got2 := tc.account.Close()
if !reflect.DeepEqual(tc.want1, got) {
t.Fatalf("%s expected: %v, got: %v", tc.name, tc.want1, got)
}
if !reflect.DeepEqual(tc.want2, got2) {
t.Fatalf("%s expected: %v, got: %v", tc.name, tc.want2, got2)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment