Skip to content

Commit

Permalink
Merge pull request #89 from LucaBernstein/simple-calculations
Browse files Browse the repository at this point in the history
Allow simple amount calculations
  • Loading branch information
LucaBernstein authored Dec 30, 2021
2 parents 6d0fe97 + 7ced625 commit 78af03f
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 6 deletions.
42 changes: 38 additions & 4 deletions bot/transactionBuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,44 @@ func HandleFloat(m *tb.Message) (string, error) {
input = strings.ReplaceAll(input, ",", ".")
split := strings.Split(input, " ")
var (
value = split[0]
value = split[0]
currency = ""
)
if len(split) >= 3 {
return "", fmt.Errorf("Input '%s' contained too many spaces. It should only contain the value and an optional currency", input)
if len(split) > 2 {
return "", fmt.Errorf("input '%s' contained too many spaces. It should only contain the value and an optional currency", input)
}
if len(split) == 2 {
currency = " " + split[1]
}
// Should fail if tx is left open (with trailing '+' operator) and currency is given
if strings.HasSuffix(value, "+") && currency != "" {
return "", fmt.Errorf("for transactions being kept open with trailing '+' operator, no additionally specified currency is allowed")
}
if strings.Contains(value, "+") {
additionsSplit := strings.Split(value, "+")
sum := 0.0
for _, add := range additionsSplit {
v, err := strconv.ParseFloat(add, 64)
if err != nil {
return "", fmt.Errorf("tried to sum up values due to '%s' operator found, failed at value '%s': %s", "+", add, err.Error())
}
sum += v
}
return ParseAmount(sum) + currency, nil
} else if strings.Contains(value, "*") {
multiplicationsSplit := strings.Split(value, "*")
if len(multiplicationsSplit) != 2 {
return "", fmt.Errorf("expected exactly two multiplicators ('a*b')")
}
product := 1.0
for _, multiplicator := range multiplicationsSplit {
v, err := strconv.ParseFloat(multiplicator, 64)
if err != nil {
return "", fmt.Errorf("tried to sum up values due to '%s' operator found, failed at value '%s': %s", "*", multiplicator, err.Error())
}
product *= v
}
return ParseAmount(product) + currency, nil
}
v, err := strconv.ParseFloat(value, 64)
if err != nil {
Expand All @@ -47,7 +81,7 @@ func HandleFloat(m *tb.Message) (string, error) {
v *= -1
}
c.LogLocalf(TRACE, nil, "Handled float: '%s' -> %f", m.Text, v)
return input, nil
return ParseAmount(v) + currency, nil
}

func HandleRaw(m *tb.Message) (string, error) {
Expand Down
72 changes: 70 additions & 2 deletions bot/transactionBuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ func TestHandleFloat(t *testing.T) {

handledFloat, err := bot.HandleFloat(&tb.Message{Text: "27.5"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 27.5")
helpers.TestExpect(t, handledFloat, "27.5", "")
helpers.TestExpect(t, handledFloat, "27.50", "")

handledFloat, err = bot.HandleFloat(&tb.Message{Text: "27,8"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 27,8")
helpers.TestExpect(t, handledFloat, "27.8", "Should come out as clean float")
helpers.TestExpect(t, handledFloat, "27.80", "Should come out as clean float")

handledFloat, err = bot.HandleFloat(&tb.Message{Text: " 27,12 "})
helpers.TestExpect(t, err, nil, "Should not throw an error for 27,12")
Expand All @@ -35,6 +35,74 @@ func TestHandleFloat(t *testing.T) {
handledFloat, err = bot.HandleFloat(&tb.Message{Text: "4.44 USD_CUSTOM"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 4.44 USD_CUSTOM")
helpers.TestExpect(t, handledFloat, "4.44 USD_CUSTOM", "Should include custom currency")

handledFloat, err = bot.HandleFloat(&tb.Message{Text: "-5.678"})
helpers.TestExpect(t, err, nil, "Should not throw an error for -5.678")
helpers.TestExpect(t, handledFloat, "5.678", "Should use absolute value")
}

func TestHandleFloatSimpleCalculations(t *testing.T) {
// Additions should work
handledFloat, err := bot.HandleFloat(&tb.Message{Text: "10+3"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 10+3")
helpers.TestExpect(t, handledFloat, "13.00", "")

handledFloat, err = bot.HandleFloat(&tb.Message{Text: "11.45+3,12345"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 11.45+3,12345")
helpers.TestExpect(t, handledFloat, "14.57345", "")

handledFloat, err = bot.HandleFloat(&tb.Message{Text: "006+9.999"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 006+9.999")
helpers.TestExpect(t, handledFloat, "15.999", "")

// Multiplications should work
handledFloat, err = bot.HandleFloat(&tb.Message{Text: "10*3"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 10*3")
helpers.TestExpect(t, handledFloat, "30.00", "")

handledFloat, err = bot.HandleFloat(&tb.Message{Text: "10*3,12345"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 10*3,12345")
helpers.TestExpect(t, handledFloat, "31.2345", "")

handledFloat, err = bot.HandleFloat(&tb.Message{Text: "001.1*3.5"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 001.1*3.5")
helpers.TestExpect(t, handledFloat, "3.85", "")

// Simple calculations also work with currencies
handledFloat, err = bot.HandleFloat(&tb.Message{Text: "11*3 TEST_CUR"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 11*3 TEST_CUR")
helpers.TestExpect(t, handledFloat, "33.00 TEST_CUR", "")

handledFloat, err = bot.HandleFloat(&tb.Message{Text: "14.5+16+1+1+3 ANOTHER_CURRENCY"})
helpers.TestExpect(t, err, nil, "Should not throw an error for 14.5+16+1+1+3 ANOTHER_CURRENCY")
helpers.TestExpect(t, handledFloat, "35.50 ANOTHER_CURRENCY", "")

// Check some error behaviors
// Mixed calculation operators
_, err = bot.HandleFloat(&tb.Message{Text: "1+1*2"})
if err == nil || !strings.Contains(err.Error(), "failed at value '1*2'") {
t.Errorf("Error message should state that mixing operators is not allowed")
}
// Too many spaces in input
_, err = bot.HandleFloat(&tb.Message{Text: "some many spaces"})
if err == nil || !strings.Contains(err.Error(), "contained too many spaces") {
t.Errorf("Error message should state that amount contained too many spaces")
}
// tx left open / spaced
_, err = bot.HandleFloat(&tb.Message{Text: "1+ 1"})
if err == nil || !strings.Contains(err.Error(), "additionally specified currency is allowed") {
t.Errorf("Error message should state that no additionally specified currency is allowed for trailing + tx (left open)")
}
// Multiplications only work with exactly two multiplicators
_, err = bot.HandleFloat(&tb.Message{Text: "1*1*1"})
if err == nil || !strings.Contains(err.Error(), "exactly two multiplicators") {
t.Errorf("Error message should state that parser expected exactly two multiplicators")
}
// some hiccup value in multiplication
_, err = bot.HandleFloat(&tb.Message{Text: "1*EUR"})
if err == nil || !strings.Contains(err.Error(), "failed at value 'EUR'") {
t.Errorf("Error message should state that it could not interpret 'EUR' as a number: %s", err.Error())
}
}

func TestTransactionBuilding(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions helpers/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ func TestExpect(t *testing.T, e1 interface{}, e2 interface{}, msg string) {
errorMsg := "Expected '%v' to be '%v'"
if msg != "" {
errorMsg = "%s -> " + errorMsg
} else {
errorMsg = "%s" + errorMsg
}
t.Errorf(errorMsg, msg, e1, e2)
}
Expand Down

0 comments on commit 78af03f

Please sign in to comment.