From 7a22e197f6b220c61be57786526a218aca5eb41d Mon Sep 17 00:00:00 2001 From: Ayoob Mohammed Date: Tue, 9 Aug 2022 22:51:15 +0300 Subject: [PATCH 1/4] Add Add,Subtract,Multiply many --- money.go | 38 ++++++++++++++++++ money_test.go | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) diff --git a/money.go b/money.go index e735771..343bac8 100644 --- a/money.go +++ b/money.go @@ -206,6 +206,20 @@ func (m *Money) Add(om *Money) (*Money, error) { return &Money{amount: mutate.calc.add(m.amount, om.amount), currency: m.currency}, nil } +func (m *Money) AddMany(om ...*Money) (*Money, error) { + k := New(0, m.currency.Code) + + for i := 0; i < len(om); i++ { + if err := m.assertSameCurrency(om[i]); err != nil { + return nil, err + } + + k.amount = mutate.calc.add(k.amount, om[i].amount) + } + + return &Money{amount: mutate.calc.add(m.amount, k.amount), currency: m.currency}, nil +} + // Subtract returns new Money struct with value representing difference of Self and Other Money. func (m *Money) Subtract(om *Money) (*Money, error) { if err := m.assertSameCurrency(om); err != nil { @@ -215,11 +229,35 @@ func (m *Money) Subtract(om *Money) (*Money, error) { return &Money{amount: mutate.calc.subtract(m.amount, om.amount), currency: m.currency}, nil } +func (m *Money) SubtractMany(om ...*Money) (*Money, error) { + k := New(0, m.currency.Code) + + for i := 0; i < len(om); i++ { + if err := m.assertSameCurrency(om[i]); err != nil { + return nil, err + } + + k.amount = mutate.calc.add(k.amount, om[i].amount) + } + + return &Money{amount: mutate.calc.subtract(m.amount, k.amount), currency: m.currency}, nil +} + // Multiply returns new Money struct with value representing Self multiplied value by multiplier. func (m *Money) Multiply(mul int64) *Money { return &Money{amount: mutate.calc.multiply(m.amount, mul), currency: m.currency} } +func (m *Money) MultiplyMany(mul ...int64) *Money { + k := New(1, m.currency.Code) + + for i := 0; i < len(mul); i++ { + k.amount = mutate.calc.multiply(k.amount, mul[i]) + } + + return &Money{amount: mutate.calc.multiply(m.amount, k.amount), currency: m.currency} +} + // Round returns new Money struct with value rounded to nearest zero. func (m *Money) Round() *Money { return &Money{amount: mutate.calc.round(m.amount, m.currency.Fraction), currency: m.currency} diff --git a/money_test.go b/money_test.go index 196f5b5..eb6a1ee 100644 --- a/money_test.go +++ b/money_test.go @@ -320,6 +320,47 @@ func TestMoney_Add2(t *testing.T) { } } +func TestMoney_AddMany(t *testing.T) { + tcs := []struct { + amount1 int64 + amount2 int64 + amount3 int64 + expected int64 + }{ + {5, 5, 3, 13}, + {10, 5, 4, 19}, + {1, -1, 2, 2}, + {3, -1, -4, -2}, + } + + for _, tc := range tcs { + mon1 := New(tc.amount1, EUR) + mon2 := New(tc.amount2, EUR) + mon3 := New(tc.amount3, EUR) + r, err := mon1.AddMany(mon2, mon3) + + if err != nil { + t.Error(err) + } + + if r.Amount() != tc.expected { + t.Errorf("Expected %d + %d + %d = %d got %d", tc.amount1, tc.amount2, tc.amount3, + tc.expected, r.amount) + } + } +} + +func TestMoney_AddMany2(t *testing.T) { + mon1 := New(100, GBP) + mon2 := New(100, EUR) + mon3 := New(100, GBP) + r, err := mon1.AddMany(mon2, mon3) + + if r != nil || err == nil { + t.Error("Expected err") + } +} + func TestMoney_Subtract(t *testing.T) { tcs := []struct { amount1 int64 @@ -357,6 +398,47 @@ func TestMoney_Subtract2(t *testing.T) { } } +func TestMoney_SubtractMany(t *testing.T) { + tcs := []struct { + amount1 int64 + amount2 int64 + amount3 int64 + expected int64 + }{ + {5, 5, 3, -3}, + {10, -5, 4, 11}, + {1, -1, 2, 0}, + {7, 1, -4, 10}, + } + + for _, tc := range tcs { + mon1 := New(tc.amount1, EUR) + mon2 := New(tc.amount2, EUR) + mon3 := New(tc.amount3, EUR) + r, err := mon1.SubtractMany(mon2, mon3) + + if err != nil { + t.Error(err) + } + + if r.Amount() != tc.expected { + t.Errorf("Expected (%d) - (%d) - (%d) = %d got %d", tc.amount1, tc.amount2, tc.amount3, + tc.expected, r.amount) + } + } +} + +func TestMoney_SubtractMany2(t *testing.T) { + mon1 := New(100, GBP) + mon2 := New(100, EUR) + mon3 := New(100, GBP) + r, err := mon1.SubtractMany(mon2, mon3) + + if r != nil || err == nil { + t.Error("Expected err") + } +} + func TestMoney_Multiply(t *testing.T) { tcs := []struct { amount int64 @@ -379,6 +461,29 @@ func TestMoney_Multiply(t *testing.T) { } } +func TestMoney_MultiplyMany(t *testing.T) { + tcs := []struct { + amount1 int64 + amount2 int64 + amount3 int64 + expected int64 + }{ + {5, 5, 5, 125}, + {10, 5, -3, -150}, + {1, -1, 6, -6}, + {1, 0, 2, 0}, + } + + for _, tc := range tcs { + mon1 := New(tc.amount1, EUR) + r := mon1.MultiplyMany(tc.amount2, tc.amount3) + + if r.amount != tc.expected { + t.Errorf("Expected %d * %d * %d = %d got %d", tc.amount1, tc.amount2, tc.amount3, tc.expected, r.amount) + } + } +} + func TestMoney_Round(t *testing.T) { tcs := []struct { amount int64 From 808c5c014834dab7b5a41e01a3024160cc779493 Mon Sep 17 00:00:00 2001 From: Ayoob Mohammed Date: Tue, 9 Aug 2022 23:02:46 +0300 Subject: [PATCH 2/4] Add docs --- README.md | 28 ++++++++++++++++++++++++++++ money.go | 3 +++ 2 files changed, 31 insertions(+) diff --git a/README.md b/README.md index d97747d..676d16a 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,16 @@ twoPounds := money.New(200, money.GBP) result, err := pound.Add(twoPounds) // £3.00, nil ``` +Also, you can perform addition with many values using `AddMany()` + +```go +pound := money.New(100, money.GBP) +twoPounds := money.New(200, money.GBP) +threePounds := money.New(300, money.GBP) + +result, err := pound.AddMany(twoPounds, threePounds) // £6.00, nil +``` + #### Subtraction Subtraction can be performed using `Subtract()`. @@ -150,6 +160,16 @@ twoPounds := money.New(200, money.GBP) result, err := pound.Subtract(twoPounds) // -£1.00, nil ``` +Also, you can perform subtraction with many values using `SubtractMany()` + +```go +pound := money.New(100, money.GBP) +twoPounds := money.New(200, money.GBP) +threePounds := money.New(300, money.GBP) + +result, err := pound.SubtractMany(twoPounds, threePounds) // -£4.00, nil +``` + #### Multiplication Multiplication can be performed using `Multiply()`. @@ -160,6 +180,14 @@ pound := money.New(100, money.GBP) result := pound.Multiply(2) // £2.00 ``` +Also, you can perform multiplication with many values using `MultiplyMany()` + +```go +pound := money.New(100, money.GBP) + +result := pound.MultiplyMany(2, 3) // £6.00 +``` + #### Absolute Return `absolute` value of Money structure diff --git a/money.go b/money.go index 343bac8..b029a4b 100644 --- a/money.go +++ b/money.go @@ -206,6 +206,7 @@ func (m *Money) Add(om *Money) (*Money, error) { return &Money{amount: mutate.calc.add(m.amount, om.amount), currency: m.currency}, nil } +// AddMany returns new Money struct with value representing sum of Self and Other Many Money. func (m *Money) AddMany(om ...*Money) (*Money, error) { k := New(0, m.currency.Code) @@ -229,6 +230,7 @@ func (m *Money) Subtract(om *Money) (*Money, error) { return &Money{amount: mutate.calc.subtract(m.amount, om.amount), currency: m.currency}, nil } +// SubtractMany returns new Money struct with value representing difference of Self and Other Many Money. func (m *Money) SubtractMany(om ...*Money) (*Money, error) { k := New(0, m.currency.Code) @@ -248,6 +250,7 @@ func (m *Money) Multiply(mul int64) *Money { return &Money{amount: mutate.calc.multiply(m.amount, mul), currency: m.currency} } +// Multiply returns new Money struct with value representing Self multiplied value by many multipliers. func (m *Money) MultiplyMany(mul ...int64) *Money { k := New(1, m.currency.Code) From 928f8df66d3266df0a0920403df3e785eec218f1 Mon Sep 17 00:00:00 2001 From: Ayoob Mohammed Date: Wed, 10 Aug 2022 20:54:23 +0300 Subject: [PATCH 3/4] Add variadic parameters --- README.md | 28 ---------------------------- money.go | 31 ++++++++++--------------------- money_test.go | 34 ++++++---------------------------- 3 files changed, 16 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index 676d16a..d97747d 100644 --- a/README.md +++ b/README.md @@ -139,16 +139,6 @@ twoPounds := money.New(200, money.GBP) result, err := pound.Add(twoPounds) // £3.00, nil ``` -Also, you can perform addition with many values using `AddMany()` - -```go -pound := money.New(100, money.GBP) -twoPounds := money.New(200, money.GBP) -threePounds := money.New(300, money.GBP) - -result, err := pound.AddMany(twoPounds, threePounds) // £6.00, nil -``` - #### Subtraction Subtraction can be performed using `Subtract()`. @@ -160,16 +150,6 @@ twoPounds := money.New(200, money.GBP) result, err := pound.Subtract(twoPounds) // -£1.00, nil ``` -Also, you can perform subtraction with many values using `SubtractMany()` - -```go -pound := money.New(100, money.GBP) -twoPounds := money.New(200, money.GBP) -threePounds := money.New(300, money.GBP) - -result, err := pound.SubtractMany(twoPounds, threePounds) // -£4.00, nil -``` - #### Multiplication Multiplication can be performed using `Multiply()`. @@ -180,14 +160,6 @@ pound := money.New(100, money.GBP) result := pound.Multiply(2) // £2.00 ``` -Also, you can perform multiplication with many values using `MultiplyMany()` - -```go -pound := money.New(100, money.GBP) - -result := pound.MultiplyMany(2, 3) // £6.00 -``` - #### Absolute Return `absolute` value of Money structure diff --git a/money.go b/money.go index b029a4b..cdbc75e 100644 --- a/money.go +++ b/money.go @@ -198,16 +198,11 @@ func (m *Money) Negative() *Money { } // Add returns new Money struct with value representing sum of Self and Other Money. -func (m *Money) Add(om *Money) (*Money, error) { - if err := m.assertSameCurrency(om); err != nil { - return nil, err +func (m *Money) Add(om ...*Money) (*Money, error) { + if len(om) == 0 { + panic("At least one Money is required to add") } - return &Money{amount: mutate.calc.add(m.amount, om.amount), currency: m.currency}, nil -} - -// AddMany returns new Money struct with value representing sum of Self and Other Many Money. -func (m *Money) AddMany(om ...*Money) (*Money, error) { k := New(0, m.currency.Code) for i := 0; i < len(om); i++ { @@ -222,16 +217,11 @@ func (m *Money) AddMany(om ...*Money) (*Money, error) { } // Subtract returns new Money struct with value representing difference of Self and Other Money. -func (m *Money) Subtract(om *Money) (*Money, error) { - if err := m.assertSameCurrency(om); err != nil { - return nil, err +func (m *Money) Subtract(om ...*Money) (*Money, error) { + if len(om) == 0 { + panic("At least one Money is required to subtract") } - return &Money{amount: mutate.calc.subtract(m.amount, om.amount), currency: m.currency}, nil -} - -// SubtractMany returns new Money struct with value representing difference of Self and Other Many Money. -func (m *Money) SubtractMany(om ...*Money) (*Money, error) { k := New(0, m.currency.Code) for i := 0; i < len(om); i++ { @@ -246,12 +236,11 @@ func (m *Money) SubtractMany(om ...*Money) (*Money, error) { } // Multiply returns new Money struct with value representing Self multiplied value by multiplier. -func (m *Money) Multiply(mul int64) *Money { - return &Money{amount: mutate.calc.multiply(m.amount, mul), currency: m.currency} -} +func (m *Money) Multiply(mul ...int64) *Money { + if len(mul) == 0 { + panic("At least one multiplier is required to multiply") + } -// Multiply returns new Money struct with value representing Self multiplied value by many multipliers. -func (m *Money) MultiplyMany(mul ...int64) *Money { k := New(1, m.currency.Code) for i := 0; i < len(mul); i++ { diff --git a/money_test.go b/money_test.go index eb6a1ee..9a221da 100644 --- a/money_test.go +++ b/money_test.go @@ -320,7 +320,7 @@ func TestMoney_Add2(t *testing.T) { } } -func TestMoney_AddMany(t *testing.T) { +func TestMoney_Add3(t *testing.T) { tcs := []struct { amount1 int64 amount2 int64 @@ -337,7 +337,7 @@ func TestMoney_AddMany(t *testing.T) { mon1 := New(tc.amount1, EUR) mon2 := New(tc.amount2, EUR) mon3 := New(tc.amount3, EUR) - r, err := mon1.AddMany(mon2, mon3) + r, err := mon1.Add(mon2, mon3) if err != nil { t.Error(err) @@ -350,17 +350,6 @@ func TestMoney_AddMany(t *testing.T) { } } -func TestMoney_AddMany2(t *testing.T) { - mon1 := New(100, GBP) - mon2 := New(100, EUR) - mon3 := New(100, GBP) - r, err := mon1.AddMany(mon2, mon3) - - if r != nil || err == nil { - t.Error("Expected err") - } -} - func TestMoney_Subtract(t *testing.T) { tcs := []struct { amount1 int64 @@ -398,7 +387,7 @@ func TestMoney_Subtract2(t *testing.T) { } } -func TestMoney_SubtractMany(t *testing.T) { +func TestMoney_Subtract3(t *testing.T) { tcs := []struct { amount1 int64 amount2 int64 @@ -415,7 +404,7 @@ func TestMoney_SubtractMany(t *testing.T) { mon1 := New(tc.amount1, EUR) mon2 := New(tc.amount2, EUR) mon3 := New(tc.amount3, EUR) - r, err := mon1.SubtractMany(mon2, mon3) + r, err := mon1.Subtract(mon2, mon3) if err != nil { t.Error(err) @@ -428,17 +417,6 @@ func TestMoney_SubtractMany(t *testing.T) { } } -func TestMoney_SubtractMany2(t *testing.T) { - mon1 := New(100, GBP) - mon2 := New(100, EUR) - mon3 := New(100, GBP) - r, err := mon1.SubtractMany(mon2, mon3) - - if r != nil || err == nil { - t.Error("Expected err") - } -} - func TestMoney_Multiply(t *testing.T) { tcs := []struct { amount int64 @@ -461,7 +439,7 @@ func TestMoney_Multiply(t *testing.T) { } } -func TestMoney_MultiplyMany(t *testing.T) { +func TestMoney_Multiply2(t *testing.T) { tcs := []struct { amount1 int64 amount2 int64 @@ -476,7 +454,7 @@ func TestMoney_MultiplyMany(t *testing.T) { for _, tc := range tcs { mon1 := New(tc.amount1, EUR) - r := mon1.MultiplyMany(tc.amount2, tc.amount3) + r := mon1.Multiply(tc.amount2, tc.amount3) if r.amount != tc.expected { t.Errorf("Expected %d * %d * %d = %d got %d", tc.amount1, tc.amount2, tc.amount3, tc.expected, r.amount) From cc3f435315c3ddfd143bb27efca4473d7e39da9e Mon Sep 17 00:00:00 2001 From: Ayoob Mohammed Date: Fri, 19 Aug 2022 19:28:16 +0300 Subject: [PATCH 4/4] remove panic --- money.go | 32 ++++++++++++++++---------------- money_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/money.go b/money.go index cdbc75e..399dd19 100644 --- a/money.go +++ b/money.go @@ -198,53 +198,53 @@ func (m *Money) Negative() *Money { } // Add returns new Money struct with value representing sum of Self and Other Money. -func (m *Money) Add(om ...*Money) (*Money, error) { - if len(om) == 0 { - panic("At least one Money is required to add") +func (m *Money) Add(ms ...*Money) (*Money, error) { + if len(ms) == 0 { + return m, nil } k := New(0, m.currency.Code) - for i := 0; i < len(om); i++ { - if err := m.assertSameCurrency(om[i]); err != nil { + for _, m2 := range ms { + if err := m.assertSameCurrency(m2); err != nil { return nil, err } - k.amount = mutate.calc.add(k.amount, om[i].amount) + k.amount = mutate.calc.add(k.amount, m2.amount) } return &Money{amount: mutate.calc.add(m.amount, k.amount), currency: m.currency}, nil } // Subtract returns new Money struct with value representing difference of Self and Other Money. -func (m *Money) Subtract(om ...*Money) (*Money, error) { - if len(om) == 0 { - panic("At least one Money is required to subtract") +func (m *Money) Subtract(ms ...*Money) (*Money, error) { + if len(ms) == 0 { + return m, nil } k := New(0, m.currency.Code) - for i := 0; i < len(om); i++ { - if err := m.assertSameCurrency(om[i]); err != nil { + for _, m2 := range ms { + if err := m.assertSameCurrency(m2); err != nil { return nil, err } - k.amount = mutate.calc.add(k.amount, om[i].amount) + k.amount = mutate.calc.add(k.amount, m2.amount) } return &Money{amount: mutate.calc.subtract(m.amount, k.amount), currency: m.currency}, nil } // Multiply returns new Money struct with value representing Self multiplied value by multiplier. -func (m *Money) Multiply(mul ...int64) *Money { - if len(mul) == 0 { +func (m *Money) Multiply(muls ...int64) *Money { + if len(muls) == 0 { panic("At least one multiplier is required to multiply") } k := New(1, m.currency.Code) - for i := 0; i < len(mul); i++ { - k.amount = mutate.calc.multiply(k.amount, mul[i]) + for _, m2 := range muls { + k.amount = mutate.calc.multiply(k.amount, m2) } return &Money{amount: mutate.calc.multiply(m.amount, k.amount), currency: m.currency} diff --git a/money_test.go b/money_test.go index 9a221da..13ba2b0 100644 --- a/money_test.go +++ b/money_test.go @@ -350,6 +350,19 @@ func TestMoney_Add3(t *testing.T) { } } +func TestMoney_Add4(t *testing.T) { + m := New(100, EUR) + r, err := m.Add() + + if err != nil { + t.Error(err) + } + + if r.amount != 100 { + t.Error("Expected amount to be 100") + } +} + func TestMoney_Subtract(t *testing.T) { tcs := []struct { amount1 int64 @@ -417,6 +430,19 @@ func TestMoney_Subtract3(t *testing.T) { } } +func TestMoney_Subtract4(t *testing.T) { + m := New(100, EUR) + r, err := m.Subtract() + + if err != nil { + t.Error(err) + } + + if r.amount != 100 { + t.Error("Expected amount to be 100") + } +} + func TestMoney_Multiply(t *testing.T) { tcs := []struct { amount int64